harness-wingman 0.9.4 → 0.9.6
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/apps/cli/dist/main.js +651 -159
- package/apps/panel/dist/assets/index-BI0dh42d.css +1 -0
- package/apps/panel/dist/assets/index-eznJMUFr.js +355 -0
- package/apps/panel/dist/index.html +2 -2
- package/package.json +2 -2
- package/apps/panel/dist/assets/index-2n853qZ8.css +0 -1
- package/apps/panel/dist/assets/index-AK2vZUEt.js +0 -344
package/apps/cli/dist/main.js
CHANGED
|
@@ -224,7 +224,7 @@ var init_cli = __esm({
|
|
|
224
224
|
"cli.adapterFactoryMissing": "adapter-{harness} does not export createAdapter (M1 parallel work not merged?)",
|
|
225
225
|
"cli.adapterFeedbackMissing": "adapter-{harness} does not export feedbackSignals",
|
|
226
226
|
"cli.fixturesUnavailable": "--fixtures requires packages/fixtures data from the repository; release packages and npx distributions do not include samples",
|
|
227
|
-
"cli.help": "wingman \u2014 Not your copilot. Your wingman.\n\nUsage:\n wingman [--locale <tag>] <command> Interface language (e.g. zh, en)\n wingman scan --harness <cc|codex|dsh> [--json] Scan a harness and print UnifiedConfig\n wingman serve [--port 7333] [--fixtures] Start the local panel (127.0.0.1 only)\n [--panel-dist <dir>] Panel files (default: apps/panel/dist)\n wingman hook install <harness> [--port 7333] Install live hooks (backup first, idempotent)\n [--profile <p>] dsh: process only this profile\n wingman hook uninstall <harness> [--profile <p>] Remove hooks and restore configuration\n wingman protocol install|uninstall|status <harness> Manage user / project Plan protocol\n [--project <dir> | --user] [--dry-run] [--yes]\n wingman license status Show
|
|
227
|
+
"cli.help": "wingman \u2014 Not your copilot. Your wingman.\n\nUsage:\n wingman [--locale <tag>] <command> Interface language (e.g. zh, en)\n wingman scan --harness <cc|codex|dsh> [--json] Scan a harness and print UnifiedConfig\n wingman serve [--port 7333] [--fixtures] Start the local panel (127.0.0.1 only)\n [--panel-dist <dir>] Panel files (default: apps/panel/dist)\n wingman hook install <harness> [--port 7333] Install live hooks (backup first, idempotent)\n [--profile <p>] dsh: process only this profile\n wingman hook uninstall <harness> [--profile <p>] Remove hooks and restore configuration\n wingman protocol install|uninstall|status <harness> Manage user / project Plan protocol\n [--project <dir> | --user] [--dry-run] [--yes]\n wingman license status Show license status\n wingman license refresh Renew the license online\n wingman --version | -v | version Show version\n wingman help Show this help\n",
|
|
228
228
|
"cli.licenseUsage": "License usage: wingman license status|refresh",
|
|
229
229
|
"cli.unknownCommand": "Unknown command: {command}",
|
|
230
230
|
"cli.scanNotDetected": "wingman: {harness} was not detected; nothing to scan.\n",
|
|
@@ -278,19 +278,19 @@ var init_cli = __esm({
|
|
|
278
278
|
"cli.protocolFixtures": "protocol does not support --fixtures",
|
|
279
279
|
"cli.protocolTruncation": "Warning: Codex may truncate this block; AGENTS.md is near or above the default 32 KiB project_doc_max_bytes after installation.\n",
|
|
280
280
|
"cli.confirmWrite": "Confirm write? [y/N] ",
|
|
281
|
-
"cli.licenseMissing": "No license installed
|
|
282
|
-
"cli.licenseDevelopment": "Development build: no embedded public key;
|
|
281
|
+
"cli.licenseMissing": "No license installed; the free tier shows one tool. A trial or subscription unlocks all three tools, the project overview and config toggles.",
|
|
282
|
+
"cli.licenseDevelopment": "Development build: no embedded public key; all features are available",
|
|
283
283
|
"cli.licenseJson": "The license file is not valid JSON",
|
|
284
284
|
"cli.licenseFields": "The license file is missing token/signature fields",
|
|
285
285
|
"cli.licenseSignature": "License signature verification failed (modified content or issued for another product)",
|
|
286
286
|
"cli.licenseClaimsFields": "License payload fields are incomplete",
|
|
287
287
|
"cli.licenseClaimsDecode": "The license payload could not be decoded",
|
|
288
288
|
"cli.licenseValidUntil": "{plan} valid until {exp}",
|
|
289
|
-
"cli.trialExpired": "Your trial expired on {exp};
|
|
289
|
+
"cli.trialExpired": "Your trial expired on {exp}; the free tier shows one tool. A trial or subscription unlocks all three tools, the project overview and config toggles.",
|
|
290
290
|
"cli.licenseGrace": "Your subscription expired on {exp} and is within the {days}-day offline grace period (connect to renew)",
|
|
291
|
-
"cli.subscriptionExpired": "Your subscription expired on {exp} and its grace period has ended;
|
|
291
|
+
"cli.subscriptionExpired": "Your subscription expired on {exp} and its grace period has ended; the free tier shows one tool. A trial or subscription unlocks all three tools, the project overview and config toggles.",
|
|
292
292
|
"cli.licenseWriteFailed": "Could not write {path}: {message}",
|
|
293
|
-
"cli.refreshMissing": "Could not find {path}.
|
|
293
|
+
"cli.refreshMissing": "Could not find {path}. Import a trial or subscription license.json first.",
|
|
294
294
|
"cli.refreshNetwork": "Could not connect. Try again later; your current license is unchanged",
|
|
295
295
|
"cli.refreshHttp": "The license server returned HTTP {status}",
|
|
296
296
|
"cli.refreshRejected": "Renewal rejected: {detail}",
|
|
@@ -553,8 +553,11 @@ var init_panel = __esm({
|
|
|
553
553
|
"panel.live.disconnectedReconnectingAutomatically": "Disconnected \xB7 Reconnecting automatically",
|
|
554
554
|
"panel.live.connecting": "Connecting\u2026",
|
|
555
555
|
"panel.taskboard.waitingForYou": "Waiting for you",
|
|
556
|
+
"panel.taskboard.turnEnded": "Turn ended",
|
|
556
557
|
"panel.taskboard.ended": "Ended",
|
|
557
558
|
"panel.taskboard.inProgress": "In progress",
|
|
559
|
+
"panel.taskboard.allowed": "Allowed",
|
|
560
|
+
"panel.taskboard.denied": "Declined",
|
|
558
561
|
"panel.taskboard.dshHasNoObservedCommandTo": "dsh has no observed command to resume a specific session; continue in the original terminal",
|
|
559
562
|
"panel.taskboard.sourceSessionIdFromHookEvents": "Source: session id from hook events; command syntax from codex resume --help",
|
|
560
563
|
"panel.taskboard.sourceSessionIdFromHookEvents132": "Source: session id from hook events; command syntax from claude --help; run in the original project directory",
|
|
@@ -601,6 +604,7 @@ var init_panel_narrative = __esm({
|
|
|
601
604
|
"panel.narrative.event.UserPromptSubmit": "New prompt received",
|
|
602
605
|
"panel.narrative.event.PreToolUse": "Tool call started",
|
|
603
606
|
"panel.narrative.event.PostToolUse": "Tool call completed",
|
|
607
|
+
"panel.narrative.event.userRejected": "You declined",
|
|
604
608
|
"panel.narrative.event.Stop": "Turn ended",
|
|
605
609
|
"panel.narrative.event.Notification": "Notification received",
|
|
606
610
|
"panel.narrative.event.PermissionRequest": "Waiting for permission",
|
|
@@ -622,6 +626,10 @@ var init_render = __esm({
|
|
|
622
626
|
"panel.render.originCli": "Codex CLI",
|
|
623
627
|
"panel.render.originDesktop": "Codex Desktop",
|
|
624
628
|
"panel.render.originSource": "Source: session_meta.originator / source",
|
|
629
|
+
"panel.render.chipNoInstruction": "No instruction yet \xB7 {p0}",
|
|
630
|
+
"panel.render.chipDirectory": "Directory: {p0}",
|
|
631
|
+
"panel.render.chipTitleSource": "Title source: {p0}",
|
|
632
|
+
"panel.render.chipTurnEnded": "Turn ended (no events or transcript activity since Stop)",
|
|
625
633
|
"panel.render.projectsPageTitle": "Project overview",
|
|
626
634
|
"panel.render.projectsPageHint": "Goals, progress and decisions across your coding apps.",
|
|
627
635
|
"panel.render.controlsPageHint": "Manage tools, preferences and how you return to a session.",
|
|
@@ -644,6 +652,7 @@ var init_render = __esm({
|
|
|
644
652
|
"panel.render.olderSessions": "{count} older sessions",
|
|
645
653
|
"panel.render.olderSessionsSource": "Source: sessions.ended and lastActivity more than {days} days ago; display only",
|
|
646
654
|
"panel.render.archiveSession": "Archive",
|
|
655
|
+
"panel.render.archiveThisSession": "Archive this session",
|
|
647
656
|
"panel.render.restoreSession": "Restore",
|
|
648
657
|
"panel.render.archivedSessions": "Archived sessions ({count})",
|
|
649
658
|
"panel.render.sessionArchiveSource": "Source: local task-overlay.json session / project archived; harness data is retained",
|
|
@@ -822,17 +831,34 @@ var init_render = __esm({
|
|
|
822
831
|
"panel.render.commonCausesFilesChangedAfterPlanning": "Common causes: files changed after planning (close and reopen the toggle to plan again), itemId is missing, or the target format is unknown and cannot be safely written.",
|
|
823
832
|
"panel.render.closeDialog": "Close dialog",
|
|
824
833
|
"panel.render.dayFreeTrialUntil": "30-day free trial until {p0}",
|
|
834
|
+
"panel.render.dayFreeTrialEnding": "30-day free trial until {p0} \xB7 then the free tier (one tool)",
|
|
835
|
+
"panel.render.freeTierHarness": "Free tier tool",
|
|
836
|
+
"panel.render.freeTierBarLabel": "Free tier",
|
|
837
|
+
"panel.render.freeTierBarChoose": "Choose one tool. You can change it after 7 days",
|
|
838
|
+
"panel.render.freeTierBarCurrent": "Current tool: {tool}",
|
|
839
|
+
"panel.render.freeTierBarDay": "Change in {days} day",
|
|
840
|
+
"panel.render.freeTierBarDays": "Change in {days} days",
|
|
841
|
+
"panel.render.freeTierBarToday": "Can change today",
|
|
842
|
+
"panel.render.freeTierBarChange": "Change",
|
|
843
|
+
"panel.render.freeTierBarSwitchableAt": "Can change on {date}",
|
|
844
|
+
"panel.render.freeTierModalTitle": "Free tier shows one tool",
|
|
845
|
+
"panel.render.freeTierModalBody": "You are currently viewing {tool}. A trial or subscription unlocks all three tools, the cross-tool project overview and write access to config toggles.",
|
|
846
|
+
"panel.render.freeTierModalTrial": "Start the 30-day free trial",
|
|
847
|
+
"panel.render.freeTierModalDismiss": "Not now",
|
|
848
|
+
"panel.render.freeTierModalExisting": "Already have a license?",
|
|
849
|
+
"panel.render.freeTierModalImport": "Import",
|
|
850
|
+
"panel.render.freeTierModalRefresh": "Refresh",
|
|
825
851
|
"panel.render.dayFreeTrialActive": "30-day free trial active",
|
|
826
|
-
"panel.render.freeTrialEndedRefreshOrSubscribe": "Free trial ended \xB7 refresh or subscribe",
|
|
852
|
+
"panel.render.freeTrialEndedRefreshOrSubscribe": "Free trial ended \xB7 the free tier shows one tool \xB7 refresh or subscribe",
|
|
827
853
|
"panel.render.subscriptionExpiredInGracePeriodRenew": "Subscription expired, in grace period \xB7 renew",
|
|
828
|
-
"panel.render.
|
|
854
|
+
"panel.render.subscriptionExpiredFreeTier": "Subscription expired \xB7 the free tier shows one tool \xB7 refresh or subscribe",
|
|
829
855
|
"panel.render.importLicenseJsonFromTheActivation": "Import license.json from the activation page (writes ~/.wingman/license.json and backs up the old file), or drag the file into this panel",
|
|
830
856
|
"panel.render.importLicense": "Import license",
|
|
831
857
|
"panel.render.cancelSubscriptionsOrChangePaymentMethods": "Cancel subscriptions or change payment methods through Stripe using the links in emails sent to your subscription address.",
|
|
832
858
|
"panel.render.manageSubscriptionCancelPaymentMethodInvoices": "Manage subscription (cancel / payment method / invoices)",
|
|
833
859
|
"panel.render.refreshLicense": "Refresh license",
|
|
834
860
|
"panel.render.afterPaymentOrWhileYourSubscription": "After payment, or while your subscription is active, refresh to restore the latest status. Only this button contacts the license service.",
|
|
835
|
-
"panel.render.keepUsingWriteFeatures": "
|
|
861
|
+
"panel.render.keepUsingWriteFeatures": "Unlock all three tools, the project overview and config toggles",
|
|
836
862
|
"panel.render.subscribeToWingman": "Subscribe to Wingman",
|
|
837
863
|
"panel.render.refreshing": "Refreshing\u2026",
|
|
838
864
|
"panel.render.freeTrial": "Free trial",
|
|
@@ -882,11 +908,12 @@ var init_render = __esm({
|
|
|
882
908
|
"panel.render.endedSessionEndOrNoEventsFor": "Ended (SessionEnd, or no events for 10 minutes after Stop)",
|
|
883
909
|
"panel.render.inProgress": "In progress",
|
|
884
910
|
"panel.render.waitingForYouAnOpenPermission": "Waiting for you: an open permission request or notification",
|
|
911
|
+
"panel.render.discoveredOnStartup": "Registered by the startup scan; no hook events yet",
|
|
885
912
|
"panel.render.newActivitySinceLastViewed": "New activity since last viewed",
|
|
886
|
-
"panel.render.newActivity": "New activity",
|
|
887
913
|
"panel.render.sinceWingmanStarted": "Since Wingman started (",
|
|
888
914
|
"panel.render.noHookEventsReceivedFrom": "), no hook events received from",
|
|
889
|
-
"panel.render.sessionsAreCreatedFromEventsOnly": ";
|
|
915
|
+
"panel.render.sessionsAreCreatedFromEventsOnly": "; startup only registers session transcripts updated in the last 30 minutes; older sessions are not restored.",
|
|
916
|
+
"panel.render.sessionsAreCreatedFromEventsOnlyDsh": "; sessions are created from events only, and history is not restored after restart.",
|
|
890
917
|
"panel.render.legacyHomeLevelWiringCouldNot": "Legacy home-level wiring could not be removed automatically; disconnect manually, then reconnect: ",
|
|
891
918
|
"panel.render.legacyHomeLevelWiringAndEarlier": "Legacy home-level wiring (0.6.0 and earlier) was removed to prevent dsh startup failures; reconnect: ",
|
|
892
919
|
"panel.render.evicted": "Evicted",
|
|
@@ -965,13 +992,12 @@ var init_render = __esm({
|
|
|
965
992
|
"panel.render.failureSuffix": " \xB7 Failed",
|
|
966
993
|
"panel.render.sourceTranscriptHookToolEventOriginal": "Source: transcript / hook tool event; original parameters: ",
|
|
967
994
|
"panel.render.noWingmanPlanMd": "No .wingman/plan.md",
|
|
968
|
-
"panel.render.loadingProjectData": "Loading project data",
|
|
969
995
|
"panel.render.projectDataUnavailable": "Project data unavailable",
|
|
970
996
|
"panel.render.openProject": "Open project",
|
|
971
997
|
"panel.render.thisSessionAttachedTo": "This session: attached to",
|
|
972
998
|
"panel.render.thisSessionUnattached": "This session: unattached (",
|
|
973
999
|
"panel.render.copyInstallCommand": "Copy install command",
|
|
974
|
-
"panel.render.currentPointPrefix": "
|
|
1000
|
+
"panel.render.currentPointPrefix": "Project current point: ",
|
|
975
1001
|
"panel.render.markedCompleteByAgentNoThe": "Agent has not declared completion (the previous instruction's plan is complete; no plan declared for this instruction)",
|
|
976
1002
|
"panel.render.agentCompletionStatus": "Agent has not declared completion",
|
|
977
1003
|
"panel.render.agentStructuredPlanStepStatesTaskWorkflow": "Agent structured plan step states; taskWorkflow.plan.forInstruction",
|
|
@@ -1212,6 +1238,7 @@ var init_render = __esm({
|
|
|
1212
1238
|
"panel.render.sourceRevisionMtimeLastWriter": "Source: revision / mtime / lastWriter",
|
|
1213
1239
|
"panel.render.all": "All",
|
|
1214
1240
|
"panel.render.waitingForYouLabel": "Waiting for you",
|
|
1241
|
+
"panel.render.turnEnded": "Turn ended",
|
|
1215
1242
|
"panel.render.ended": "Ended",
|
|
1216
1243
|
"panel.render.status": "Status",
|
|
1217
1244
|
"panel.render.dataTipSourceGETApiProjects": ' data-tip="Source: GET /api/projects request and payload validation"',
|
|
@@ -1245,7 +1272,7 @@ var init_server = __esm({
|
|
|
1245
1272
|
"cli.server.harnessRequired": "harness must be {ids}, received {harness}",
|
|
1246
1273
|
"cli.server.actionShape": 'action must have the shape {kind:"toggle", itemId, enable}',
|
|
1247
1274
|
"cli.server.fixturesAction": "Fixtures mode is read-only: actions stop at the plan and no files are written",
|
|
1248
|
-
"cli.server.subscriptionRequired": "
|
|
1275
|
+
"cli.server.subscriptionRequired": "A trial or active subscription is required to write configuration changes (the free tier shows one tool).",
|
|
1249
1276
|
"cli.server.planShape": "plan must be an ActionPlan object (returned by /api/action/plan)",
|
|
1250
1277
|
"cli.server.fixturesProtocol": "Fixtures mode is read-only: no preview or writing of the user-level protocol",
|
|
1251
1278
|
"cli.server.dshUserUnsupported": "unsupported: dsh has no user-level instruction file; install the plan protocol per project",
|
|
@@ -1267,7 +1294,9 @@ var init_server = __esm({
|
|
|
1267
1294
|
"cli.server.settingsFormat": "Cannot parse return settings or unknown version; refusing to overwrite. Check settings.json",
|
|
1268
1295
|
"cli.server.settingsWrite": "Could not back up or write return settings; settings were not overwritten. Check settings.json",
|
|
1269
1296
|
"cli.server.localeInvalid": "locale must be a registered language tag",
|
|
1270
|
-
"cli.server.settingsInvalid": "Settings require a registered locale
|
|
1297
|
+
"cli.server.settingsInvalid": "Settings require a registered locale, a valid island position and size, or a known freeHarness",
|
|
1298
|
+
"cli.server.freeHarnessNotDetected": "This tool has not been detected and cannot be selected for the free tier.",
|
|
1299
|
+
"cli.server.freeHarnessCooldown": "The free tool cannot be changed for 7 days after selection. You can change it on {switchableAt}.",
|
|
1271
1300
|
"cli.server.fixturesSettings": "Fixtures mode is read-only: language settings are not saved",
|
|
1272
1301
|
"cli.server.settingsHome": "Language settings require homeDir"
|
|
1273
1302
|
};
|
|
@@ -1499,7 +1528,7 @@ var init_cli2 = __esm({
|
|
|
1499
1528
|
"cli.adapterFactoryMissing": "adapter-{harness} \u5C1A\u672A\u5BFC\u51FA createAdapter(M1 \u5E76\u884C\u7EBF\u672A\u5408\u5E76?)",
|
|
1500
1529
|
"cli.adapterFeedbackMissing": "adapter-{harness} \u5C1A\u672A\u5BFC\u51FA feedbackSignals",
|
|
1501
1530
|
"cli.fixturesUnavailable": "--fixtures \u9700\u8981\u4ED3\u5E93\u5185\u7684 packages/fixtures \u6570\u636E;\u53D1\u5E03\u5B89\u88C5\u5305/npx \u4EA7\u7269\u4E0D\u5305\u542B\u6837\u4F8B",
|
|
1502
|
-
"cli.help": "wingman \u2014 Not your copilot. Your wingman.\n\n\u7528\u6CD5:\n wingman [--locale <tag>] <command> \u754C\u9762\u8BED\u8A00(\u5982 zh\u3001en)\n wingman scan --harness <cc|codex|dsh> [--json] \u626B\u63CF\u4E00\u4E2A harness,\u8F93\u51FA UnifiedConfig\n wingman serve [--port 7333] [--fixtures] \u542F\u52A8\u672C\u5730\u9762\u677F(\u53EA\u7ED1 127.0.0.1)\n [--panel-dist <dir>] \u9762\u677F\u9759\u6001\u4EA7\u7269\u76EE\u5F55(\u9ED8\u8BA4\u4ED3\u5E93\u5E03\u5C40 apps/panel/dist)\n wingman hook install <harness> [--port 7333] \u5B9E\u51B5\u63A5\u7EBF(\u5199\u524D\u5907\u4EFD,\u5E42\u7B49)\n [--profile <p>] dsh:\u53EA\u5904\u7406\u6307\u5B9A profile\n wingman hook uninstall <harness> [--profile <p>] \u89E3\u7EBF(\u914D\u7F6E\u6062\u590D,\u5E42\u7B49)\n wingman protocol install|uninstall|status <harness> \u7BA1\u7406\u7528\u6237\u7EA7 / \u9879\u76EE\u7EA7 Plan Protocol\n [--project <dir> | --user] [--dry-run] [--yes]\n wingman license status \u67E5\u770B\
|
|
1531
|
+
"cli.help": "wingman \u2014 Not your copilot. Your wingman.\n\n\u7528\u6CD5:\n wingman [--locale <tag>] <command> \u754C\u9762\u8BED\u8A00(\u5982 zh\u3001en)\n wingman scan --harness <cc|codex|dsh> [--json] \u626B\u63CF\u4E00\u4E2A harness,\u8F93\u51FA UnifiedConfig\n wingman serve [--port 7333] [--fixtures] \u542F\u52A8\u672C\u5730\u9762\u677F(\u53EA\u7ED1 127.0.0.1)\n [--panel-dist <dir>] \u9762\u677F\u9759\u6001\u4EA7\u7269\u76EE\u5F55(\u9ED8\u8BA4\u4ED3\u5E93\u5E03\u5C40 apps/panel/dist)\n wingman hook install <harness> [--port 7333] \u5B9E\u51B5\u63A5\u7EBF(\u5199\u524D\u5907\u4EFD,\u5E42\u7B49)\n [--profile <p>] dsh:\u53EA\u5904\u7406\u6307\u5B9A profile\n wingman hook uninstall <harness> [--profile <p>] \u89E3\u7EBF(\u914D\u7F6E\u6062\u590D,\u5E42\u7B49)\n wingman protocol install|uninstall|status <harness> \u7BA1\u7406\u7528\u6237\u7EA7 / \u9879\u76EE\u7EA7 Plan Protocol\n [--project <dir> | --user] [--dry-run] [--yes]\n wingman license status \u67E5\u770B\u6388\u6743\u72B6\u6001\n wingman license refresh \u8054\u7F51\u5411\u7B7E\u53D1\u7AEF\u6362\u65B0 license(\u7EED\u671F)\n wingman --version | -v | version \u663E\u793A\u7248\u672C\n wingman help \u663E\u793A\u672C\u5E2E\u52A9\n",
|
|
1503
1532
|
"cli.licenseUsage": "license \u7528\u6CD5:wingman license status|refresh",
|
|
1504
1533
|
"cli.unknownCommand": "\u672A\u77E5\u547D\u4EE4:{command}",
|
|
1505
1534
|
"cli.scanNotDetected": "wingman:\u672A\u68C0\u6D4B\u5230 {harness},\u65E0\u4ECE\u626B\u63CF\u3002\n",
|
|
@@ -1553,19 +1582,19 @@ var init_cli2 = __esm({
|
|
|
1553
1582
|
"cli.protocolFixtures": "protocol \u4E0D\u652F\u6301 --fixtures",
|
|
1554
1583
|
"cli.protocolTruncation": "\u8B66\u544A:Codex \u53EF\u80FD\u622A\u65AD\u672C\u5757\uFF1BAGENTS.md \u88C5\u540E\u5DF2\u63A5\u8FD1\u6216\u8D85\u8FC7\u9ED8\u8BA4 32 KiB project_doc_max_bytes\u3002\n",
|
|
1555
1584
|
"cli.confirmWrite": "\u786E\u8BA4\u5199\u5165? [y/N] ",
|
|
1556
|
-
"cli.licenseMissing": "\u672A\u5B89\u88C5 license
|
|
1557
|
-
"cli.licenseDevelopment": "\u5F00\u53D1\u6784\u5EFA:\u672A\u5D4C\u5165\u516C\u94A5,\
|
|
1585
|
+
"cli.licenseMissing": "\u672A\u5B89\u88C5 license\uFF1B\u514D\u8D39\u5C42\u53EA\u663E\u793A\u4E00\u4E2A\u5DE5\u5177\u3002\u8BD5\u7528\u6216\u8BA2\u9605\u53EF\u67E5\u770B\u5168\u90E8\u5DE5\u5177\u4E0E\u9879\u76EE\u603B\u89C8\uFF0C\u5E76\u4F7F\u7528\u914D\u7F6E\u5F00\u5173\u3002",
|
|
1586
|
+
"cli.licenseDevelopment": "\u5F00\u53D1\u6784\u5EFA:\u672A\u5D4C\u5165\u516C\u94A5,\u5168\u90E8\u529F\u80FD\u53EF\u7528",
|
|
1558
1587
|
"cli.licenseJson": "license \u6587\u4EF6\u4E0D\u662F\u5408\u6CD5 JSON",
|
|
1559
1588
|
"cli.licenseFields": "license \u6587\u4EF6\u7F3A token/signature \u5B57\u6BB5",
|
|
1560
1589
|
"cli.licenseSignature": "license \u9A8C\u7B7E\u5931\u8D25(\u5185\u5BB9\u88AB\u6539\u52A8\u6216\u975E\u672C\u4EA7\u54C1\u7B7E\u53D1)",
|
|
1561
1590
|
"cli.licenseClaimsFields": "license \u8F7D\u8377\u5B57\u6BB5\u4E0D\u5B8C\u6574",
|
|
1562
1591
|
"cli.licenseClaimsDecode": "license \u8F7D\u8377\u65E0\u6CD5\u89E3\u7801",
|
|
1563
1592
|
"cli.licenseValidUntil": "{plan}\u6709\u6548\u81F3 {exp}",
|
|
1564
|
-
"cli.trialExpired": "\u8BD5\u7528\u5DF2\u4E8E {exp} \u5230\u671F
|
|
1593
|
+
"cli.trialExpired": "\u8BD5\u7528\u5DF2\u4E8E {exp} \u5230\u671F\uFF1B\u514D\u8D39\u5C42\u53EA\u663E\u793A\u4E00\u4E2A\u5DE5\u5177\u3002\u8BD5\u7528\u6216\u8BA2\u9605\u53EF\u67E5\u770B\u5168\u90E8\u5DE5\u5177\u4E0E\u9879\u76EE\u603B\u89C8\uFF0C\u5E76\u4F7F\u7528\u914D\u7F6E\u5F00\u5173\u3002",
|
|
1565
1594
|
"cli.licenseGrace": "\u8BA2\u9605\u5DF2\u4E8E {exp} \u5230\u671F,\u5904\u4E8E {days} \u5929\u79BB\u7EBF\u5BBD\u9650\u671F(\u8BF7\u8054\u7F51\u7EED\u671F)",
|
|
1566
|
-
"cli.subscriptionExpired": "\u8BA2\u9605\u5DF2\u4E8E {exp} \u5230\u671F\u4E14\u8D85\u51FA\u5BBD\u9650\u671F
|
|
1595
|
+
"cli.subscriptionExpired": "\u8BA2\u9605\u5DF2\u4E8E {exp} \u5230\u671F\u4E14\u8D85\u51FA\u5BBD\u9650\u671F\uFF1B\u514D\u8D39\u5C42\u53EA\u663E\u793A\u4E00\u4E2A\u5DE5\u5177\u3002\u8BD5\u7528\u6216\u8BA2\u9605\u53EF\u67E5\u770B\u5168\u90E8\u5DE5\u5177\u4E0E\u9879\u76EE\u603B\u89C8\uFF0C\u5E76\u4F7F\u7528\u914D\u7F6E\u5F00\u5173\u3002",
|
|
1567
1596
|
"cli.licenseWriteFailed": "\u5199\u5165 {path} \u5931\u8D25:{message}",
|
|
1568
|
-
"cli.refreshMissing": "\u672A\u627E\u5230 {path}\
|
|
1597
|
+
"cli.refreshMissing": "\u672A\u627E\u5230 {path}\uFF1B\u8BF7\u5148\u5BFC\u5165\u8BD5\u7528\u6216\u8BA2\u9605\u7684 license.json\u3002",
|
|
1569
1598
|
"cli.refreshNetwork": "\u8054\u7F51\u5931\u8D25,\u7A0D\u540E\u518D\u8BD5;\u5F53\u524D\u6388\u6743\u72B6\u6001\u4FDD\u6301\u4E0D\u53D8",
|
|
1570
1599
|
"cli.refreshHttp": "\u7B7E\u53D1\u7AEF\u8FD4\u56DE HTTP {status}",
|
|
1571
1600
|
"cli.refreshRejected": "\u7EED\u671F\u88AB\u62D2:{detail}",
|
|
@@ -1828,8 +1857,11 @@ var init_panel2 = __esm({
|
|
|
1828
1857
|
"panel.live.disconnectedReconnectingAutomatically": "\u8FDE\u63A5\u65AD\u5F00 \xB7 \u81EA\u52A8\u91CD\u8FDE\u4E2D",
|
|
1829
1858
|
"panel.live.connecting": "\u8FDE\u63A5\u4E2D\u2026",
|
|
1830
1859
|
"panel.taskboard.waitingForYou": "\u7B49\u5F85",
|
|
1860
|
+
"panel.taskboard.turnEnded": "\u56DE\u5408\u7ED3\u675F",
|
|
1831
1861
|
"panel.taskboard.ended": "\u5DF2\u7ED3\u675F",
|
|
1832
1862
|
"panel.taskboard.inProgress": "\u8FDB\u884C\u4E2D",
|
|
1863
|
+
"panel.taskboard.allowed": "\u5DF2\u5141\u8BB8",
|
|
1864
|
+
"panel.taskboard.denied": "\u5DF2\u62D2\u7EDD",
|
|
1833
1865
|
"panel.taskboard.dshHasNoObservedCommandTo": "dsh \u672A\u63D0\u4F9B\u6309\u4F1A\u8BDD\u6062\u590D\u7684\u547D\u4EE4(\u672A\u89C2\u5BDF\u5230),\u8BF7\u5728\u539F\u7EC8\u7AEF\u7EE7\u7EED",
|
|
1834
1866
|
"panel.taskboard.sourceSessionIdFromHookEvents": "\u6765\u6E90:\u4F1A\u8BDD id \u6765\u81EA hook \u4E8B\u4EF6;\u547D\u4EE4\u5F62\u5F0F\u6765\u81EA codex resume --help",
|
|
1835
1867
|
"panel.taskboard.sourceSessionIdFromHookEvents132": "\u6765\u6E90:\u4F1A\u8BDD id \u6765\u81EA hook \u4E8B\u4EF6;\u547D\u4EE4\u5F62\u5F0F\u6765\u81EA claude --help;\u9700\u5728\u539F\u9879\u76EE\u76EE\u5F55\u8FD0\u884C",
|
|
@@ -1876,6 +1908,7 @@ var init_panel_narrative2 = __esm({
|
|
|
1876
1908
|
"panel.narrative.event.UserPromptSubmit": "\u6536\u5230\u65B0\u63D0\u793A",
|
|
1877
1909
|
"panel.narrative.event.PreToolUse": "\u5DE5\u5177\u8C03\u7528\u5F00\u59CB",
|
|
1878
1910
|
"panel.narrative.event.PostToolUse": "\u5DE5\u5177\u8C03\u7528\u5B8C\u6210",
|
|
1911
|
+
"panel.narrative.event.userRejected": "\u4F60\u62D2\u7EDD\u4E86",
|
|
1879
1912
|
"panel.narrative.event.Stop": "\u56DE\u5408\u7ED3\u675F",
|
|
1880
1913
|
"panel.narrative.event.Notification": "\u6536\u5230\u901A\u77E5",
|
|
1881
1914
|
"panel.narrative.event.PermissionRequest": "\u7B49\u5F85\u6388\u6743",
|
|
@@ -1897,6 +1930,10 @@ var init_render2 = __esm({
|
|
|
1897
1930
|
"panel.render.originCli": "Codex CLI",
|
|
1898
1931
|
"panel.render.originDesktop": "Codex \u684C\u9762\u7248",
|
|
1899
1932
|
"panel.render.originSource": "\u6765\u6E90:session_meta.originator / source",
|
|
1933
|
+
"panel.render.chipNoInstruction": "\u5C1A\u65E0\u6307\u4EE4 \xB7 {p0}",
|
|
1934
|
+
"panel.render.chipDirectory": "\u76EE\u5F55:{p0}",
|
|
1935
|
+
"panel.render.chipTitleSource": "\u6807\u9898\u6765\u6E90:{p0}",
|
|
1936
|
+
"panel.render.chipTurnEnded": "\u56DE\u5408\u7ED3\u675F(Stop \u540E\u65E0\u65B0\u4E8B\u4EF6\u6216\u8BB0\u5F55\u6D3B\u52A8)",
|
|
1900
1937
|
"panel.render.projectsPageTitle": "\u9879\u76EE\u603B\u89C8",
|
|
1901
1938
|
"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",
|
|
1902
1939
|
"panel.render.controlsPageHint": "\u7BA1\u7406\u5DE5\u5177\u3001\u504F\u597D\u8BBE\u7F6E\uFF0C\u4EE5\u53CA\u8FD4\u56DE\u4F1A\u8BDD\u7684\u65B9\u5F0F\u3002",
|
|
@@ -1919,6 +1956,7 @@ var init_render2 = __esm({
|
|
|
1919
1956
|
"panel.render.olderSessions": "\u66F4\u65E9\u7684 {count} \u4E2A\u4F1A\u8BDD",
|
|
1920
1957
|
"panel.render.olderSessionsSource": "\u6765\u6E90:sessions.ended \u4E14 lastActivity \u65E9\u4E8E\u5F53\u524D\u65F6\u95F4 {days} \u5929;\u4EC5\u6298\u53E0\u663E\u793A",
|
|
1921
1958
|
"panel.render.archiveSession": "\u5F52\u6863",
|
|
1959
|
+
"panel.render.archiveThisSession": "\u5F52\u6863\u6B64\u4F1A\u8BDD",
|
|
1922
1960
|
"panel.render.restoreSession": "\u6062\u590D",
|
|
1923
1961
|
"panel.render.archivedSessions": "\u5DF2\u5F52\u6863 {count} \u4E2A\u4F1A\u8BDD",
|
|
1924
1962
|
"panel.render.sessionArchiveSource": "\u6765\u6E90:\u672C\u673A task-overlay.json \u4F1A\u8BDD / \u9879\u76EE archived;\u4E0D\u5220\u9664 harness \u6570\u636E",
|
|
@@ -2097,17 +2135,34 @@ var init_render2 = __esm({
|
|
|
2097
2135
|
"panel.render.commonCausesFilesChangedAfterPlanning": "\u5E38\u89C1\u539F\u56E0:\u6587\u4EF6\u5728 plan \u4E4B\u540E\u88AB\u5916\u90E8\u6539\u8FC7(\u5173\u95ED\u540E\u91CD\u65B0\u70B9\u5F00\u5173\u751F\u6210\u65B0 plan)\u3001itemId \u4E0D\u5B58\u5728\u3001\u6216\u76EE\u6807\u683C\u5F0F\u672A\u77E5\u88AB\u62D2\u5199(\u4E0D\u731C,\u5982\u5B9E\u62D2\u7EDD)\u3002",
|
|
2098
2136
|
"panel.render.closeDialog": "\u5173\u95ED\u5F39\u7A97",
|
|
2099
2137
|
"panel.render.dayFreeTrialUntil": "30 \u5929\u514D\u8D39\u8BD5\u7528\u81F3 {p0}",
|
|
2138
|
+
"panel.render.dayFreeTrialEnding": "30 \u5929\u514D\u8D39\u8BD5\u7528\u81F3 {p0} \xB7 \u5230\u671F\u540E\u8F6C\u4E3A\u514D\u8D39\u5C42(\u4E00\u4E2A\u5DE5\u5177)",
|
|
2139
|
+
"panel.render.freeTierHarness": "\u514D\u8D39\u5C42\u5DE5\u5177",
|
|
2140
|
+
"panel.render.freeTierBarLabel": "\u514D\u8D39\u5C42",
|
|
2141
|
+
"panel.render.freeTierBarChoose": "\u9009\u4E00\u4E2A\u5DE5\u5177,7 \u5929\u5185\u4E0D\u80FD\u66F4\u6362",
|
|
2142
|
+
"panel.render.freeTierBarCurrent": "\u5F53\u524D\u5DE5\u5177 {tool}",
|
|
2143
|
+
"panel.render.freeTierBarDay": "{days} \u5929\u540E\u53EF\u66F4\u6362",
|
|
2144
|
+
"panel.render.freeTierBarDays": "{days} \u5929\u540E\u53EF\u66F4\u6362",
|
|
2145
|
+
"panel.render.freeTierBarToday": "\u4ECA\u5929\u53EF\u66F4\u6362",
|
|
2146
|
+
"panel.render.freeTierBarChange": "\u66F4\u6362",
|
|
2147
|
+
"panel.render.freeTierBarSwitchableAt": "\u53EF\u66F4\u6362\u65F6\u95F4:{date}",
|
|
2148
|
+
"panel.render.freeTierModalTitle": "\u514D\u8D39\u5C42\u53EA\u663E\u793A\u4E00\u4E2A\u5DE5\u5177",
|
|
2149
|
+
"panel.render.freeTierModalBody": "\u4F60\u73B0\u5728\u770B\u7684\u662F {tool}\u3002\u8BD5\u7528\u6216\u8BA2\u9605\u540E,\u4E09\u5BB6\u5DE5\u5177\u548C\u8DE8\u5DE5\u5177\u7684\u9879\u76EE\u603B\u89C8\u4E00\u8D77\u6253\u5F00,\u914D\u7F6E\u5F00\u5173\u4E5F\u80FD\u5199\u5165\u3002",
|
|
2150
|
+
"panel.render.freeTierModalTrial": "\u5F00\u59CB 30 \u5929\u514D\u8D39\u8BD5\u7528",
|
|
2151
|
+
"panel.render.freeTierModalDismiss": "\u5148\u4E0D\u7528",
|
|
2152
|
+
"panel.render.freeTierModalExisting": "\u5DF2\u6709 license?",
|
|
2153
|
+
"panel.render.freeTierModalImport": "\u5BFC\u5165 license",
|
|
2154
|
+
"panel.render.freeTierModalRefresh": "\u5237\u65B0\u6388\u6743",
|
|
2100
2155
|
"panel.render.dayFreeTrialActive": "30 \u5929\u514D\u8D39\u8BD5\u7528\u4E2D",
|
|
2101
|
-
"panel.render.freeTrialEndedRefreshOrSubscribe": "\u514D\u8D39\u8BD5\u7528\u5DF2\u7ED3\u675F \xB7 \u5237\u65B0\u6216\u8BA2\u9605",
|
|
2156
|
+
"panel.render.freeTrialEndedRefreshOrSubscribe": "\u514D\u8D39\u8BD5\u7528\u5DF2\u7ED3\u675F \xB7 \u514D\u8D39\u5C42\u53EA\u663E\u793A\u4E00\u4E2A\u5DE5\u5177 \xB7 \u5237\u65B0\u6216\u8BA2\u9605",
|
|
2102
2157
|
"panel.render.subscriptionExpiredInGracePeriodRenew": "\u8BA2\u9605\u5DF2\u5230\u671F,\u5BBD\u9650\u671F\u5185 \xB7 \u70B9\u6B64\u7EED\u671F",
|
|
2103
|
-
"panel.render.
|
|
2158
|
+
"panel.render.subscriptionExpiredFreeTier": "\u8BA2\u9605\u5DF2\u5230\u671F \xB7 \u514D\u8D39\u5C42\u53EA\u663E\u793A\u4E00\u4E2A\u5DE5\u5177 \xB7 \u5237\u65B0\u6216\u8BA2\u9605",
|
|
2104
2159
|
"panel.render.importLicenseJsonFromTheActivation": "\u9009\u62E9\u6FC0\u6D3B\u9875\u4E0B\u8F7D\u7684 license.json \u5BFC\u5165(\u5199\u5165 ~/.wingman/license.json,\u65E7\u6587\u4EF6\u81EA\u52A8\u5907\u4EFD);\u4E5F\u53EF\u628A\u6587\u4EF6\u76F4\u63A5\u62D6\u8FDB\u672C\u9762\u677F",
|
|
2105
2160
|
"panel.render.importLicense": "\u5BFC\u5165 license",
|
|
2106
2161
|
"panel.render.cancelSubscriptionsOrChangePaymentMethods": "\u53D6\u6D88\u8BA2\u9605\u6216\u66F4\u6362\u4ED8\u6B3E\u65B9\u5F0F\u9700\u5728 Stripe \u4FA7\u64CD\u4F5C,\u5165\u53E3\u5728\u8BA2\u9605\u90AE\u7BB1\u6536\u5230\u7684 Stripe \u90AE\u4EF6\u91CC\u3002",
|
|
2107
2162
|
"panel.render.manageSubscriptionCancelPaymentMethodInvoices": "\u7BA1\u7406\u8BA2\u9605(\u53D6\u6D88/\u6362\u5361/\u53D1\u7968)",
|
|
2108
2163
|
"panel.render.refreshLicense": "\u5237\u65B0\u6388\u6743",
|
|
2109
2164
|
"panel.render.afterPaymentOrWhileYourSubscription": "\u4ED8\u6B3E\u6210\u529F\u6216\u8BA2\u9605\u4ECD\u6709\u6548\u65F6,\u70B9\u51FB\u5237\u65B0\u5373\u53EF\u6062\u590D\u6700\u65B0\u72B6\u6001\u3002\u4EC5\u6B64\u6309\u94AE\u4F1A\u8054\u7CFB\u6388\u6743\u670D\u52A1\u3002",
|
|
2110
|
-
"panel.render.keepUsingWriteFeatures": "\
|
|
2165
|
+
"panel.render.keepUsingWriteFeatures": "\u89E3\u9501\u4E09\u5BB6\u5DE5\u5177\u3001\u9879\u76EE\u603B\u89C8\u4E0E\u914D\u7F6E\u5F00\u5173",
|
|
2111
2166
|
"panel.render.subscribeToWingman": "\u8BA2\u9605 Wingman",
|
|
2112
2167
|
"panel.render.refreshing": "\u5237\u65B0\u4E2D\u2026",
|
|
2113
2168
|
"panel.render.freeTrial": "\u514D\u8D39\u8BD5\u7528",
|
|
@@ -2157,11 +2212,12 @@ var init_render2 = __esm({
|
|
|
2157
2212
|
"panel.render.endedSessionEndOrNoEventsFor": "\u5DF2\u7ED3\u675F(SessionEnd,\u6216 Stop \u540E 10 \u5206\u949F\u65E0\u4E8B\u4EF6)",
|
|
2158
2213
|
"panel.render.inProgress": "\u8FDB\u884C\u4E2D",
|
|
2159
2214
|
"panel.render.waitingForYouAnOpenPermission": "\u7B49\u5F85:\u6709\u672A\u51B3\u7684\u6743\u9650\u8BF7\u6C42/\u901A\u77E5",
|
|
2215
|
+
"panel.render.discoveredOnStartup": "\u7531\u542F\u52A8\u626B\u63CF\u767B\u8BB0,\u5C1A\u65E0 hook \u4E8B\u4EF6",
|
|
2160
2216
|
"panel.render.newActivitySinceLastViewed": "\u6709\u65B0\u6D3B\u52A8(\u4E0A\u6B21\u67E5\u770B\u540E)",
|
|
2161
|
-
"panel.render.newActivity": "\u65B0\u6D3B\u52A8",
|
|
2162
2217
|
"panel.render.sinceWingmanStarted": "Wingman \u542F\u52A8(",
|
|
2163
2218
|
"panel.render.noHookEventsReceivedFrom": ")\u540E\u5C1A\u672A\u6536\u5230",
|
|
2164
|
-
"panel.render.sessionsAreCreatedFromEventsOnly": "\u7684 hook \u4E8B\u4EF6;\
|
|
2219
|
+
"panel.render.sessionsAreCreatedFromEventsOnly": "\u7684 hook \u4E8B\u4EF6;\u542F\u52A8\u65F6\u53EA\u767B\u8BB0\u6700\u8FD1 30 \u5206\u949F\u5185\u6709\u66F4\u65B0\u7684\u4F1A\u8BDD\u8BB0\u5F55,\u66F4\u65E9\u7684\u4E0D\u6062\u590D\u3002",
|
|
2220
|
+
"panel.render.sessionsAreCreatedFromEventsOnlyDsh": "\u7684 hook \u4E8B\u4EF6;\u4F1A\u8BDD\u53EA\u7531\u4E8B\u4EF6\u5EFA\u7ACB,\u91CD\u542F\u4E0D\u6062\u590D\u5386\u53F2\u3002",
|
|
2165
2221
|
"panel.render.legacyHomeLevelWiringCouldNot": "\u65E7\u7248\u5BB6\u76EE\u5F55\u5C42\u63A5\u7EBF\u65E0\u6CD5\u81EA\u52A8\u89E3\u9664,\u8BF7\u624B\u52A8\u89E3\u7EBF\u540E\u91CD\u65B0\u63A5\u7EBF:",
|
|
2166
2222
|
"panel.render.legacyHomeLevelWiringAndEarlier": "\u65E7\u7248(0.6.0 \u53CA\u66F4\u65E9)\u5BB6\u76EE\u5F55\u5C42\u63A5\u7EBF\u5DF2\u89E3\u9664,\u907F\u514D dsh \u65E0\u6CD5\u542F\u52A8;\u91CD\u65B0\u63A5\u7EBF:",
|
|
2167
2223
|
"panel.render.evicted": "\u5DF2\u9A71\u9010",
|
|
@@ -2240,13 +2296,12 @@ var init_render2 = __esm({
|
|
|
2240
2296
|
"panel.render.failureSuffix": " \xB7 \u5931\u8D25",
|
|
2241
2297
|
"panel.render.sourceTranscriptHookToolEventOriginal": "\u6765\u6E90:transcript / hook tool event;\u539F\u59CB\u53C2\u6570:",
|
|
2242
2298
|
"panel.render.noWingmanPlanMd": "\u6CA1\u6709 .wingman/plan.md",
|
|
2243
|
-
"panel.render.loadingProjectData": "\u9879\u76EE\u8F7D\u8377\u8F7D\u5165\u4E2D",
|
|
2244
2299
|
"panel.render.projectDataUnavailable": "\u9879\u76EE\u8F7D\u8377\u4E0D\u53EF\u7528",
|
|
2245
2300
|
"panel.render.openProject": "\u6253\u5F00\u9879\u76EE",
|
|
2246
2301
|
"panel.render.thisSessionAttachedTo": "\u672C\u4F1A\u8BDD:\u5F52\u5C5E",
|
|
2247
2302
|
"panel.render.thisSessionUnattached": "\u672C\u4F1A\u8BDD:\u672A\u5173\u8054(",
|
|
2248
2303
|
"panel.render.copyInstallCommand": "\u590D\u5236\u5B89\u88C5\u547D\u4EE4",
|
|
2249
|
-
"panel.render.currentPointPrefix": "\u5F53\u524D\u70B9:",
|
|
2304
|
+
"panel.render.currentPointPrefix": "\u9879\u76EE\u5F53\u524D\u70B9:",
|
|
2250
2305
|
"panel.render.markedCompleteByAgentNoThe": "Agent \u672A\u58F0\u660E\u5B8C\u6210(\u4E0A\u4E00\u6761\u6307\u4EE4\u7684\u8BA1\u5212\u5DF2\u5B8C\u6210,\u672C\u6761\u6307\u4EE4\u5C1A\u672A\u58F0\u660E\u8BA1\u5212)",
|
|
2251
2306
|
"panel.render.agentCompletionStatus": "Agent \u672A\u58F0\u660E\u5B8C\u6210",
|
|
2252
2307
|
"panel.render.agentStructuredPlanStepStatesTaskWorkflow": "Agent \u7ED3\u6784\u5316\u8BA1\u5212\u6B65\u9AA4\u72B6\u6001;taskWorkflow.plan.forInstruction",
|
|
@@ -2487,6 +2542,7 @@ var init_render2 = __esm({
|
|
|
2487
2542
|
"panel.render.sourceRevisionMtimeLastWriter": "\u6765\u6E90:revision / mtime / lastWriter",
|
|
2488
2543
|
"panel.render.all": "\u5168\u90E8",
|
|
2489
2544
|
"panel.render.waitingForYouLabel": "\u7B49\u5F85",
|
|
2545
|
+
"panel.render.turnEnded": "\u56DE\u5408\u7ED3\u675F",
|
|
2490
2546
|
"panel.render.ended": "\u5DF2\u7ED3\u675F",
|
|
2491
2547
|
"panel.render.status": "\u72B6\u6001",
|
|
2492
2548
|
"panel.render.dataTipSourceGETApiProjects": ' data-tip="\u6765\u6E90:GET /api/projects \u8BF7\u6C42\u4E0E\u8F7D\u8377\u6821\u9A8C"',
|
|
@@ -2520,7 +2576,7 @@ var init_server2 = __esm({
|
|
|
2520
2576
|
"cli.server.harnessRequired": "harness \u9700\u8981 {ids},\u5F97\u5230 {harness}",
|
|
2521
2577
|
"cli.server.actionShape": 'action \u9700\u8981 {kind:"toggle", itemId, enable} \u5F62\u72B6',
|
|
2522
2578
|
"cli.server.fixturesAction": "fixtures \u6A21\u5F0F\u53EA\u8BFB:\u52A8\u4F5C\u53EA\u5230 plan \u4E3A\u6B62,\u4E0D\u5199\u4EFB\u4F55\u6587\u4EF6",
|
|
2523
|
-
"cli.server.subscriptionRequired": "\u9700\u8981\u6709\u6548\u8BA2\u9605\u624D\u80FD\
|
|
2579
|
+
"cli.server.subscriptionRequired": "\u9700\u8981\u8BD5\u7528\u6216\u6709\u6548\u8BA2\u9605\u624D\u80FD\u5199\u5165\u914D\u7F6E(\u514D\u8D39\u5C42\u53EA\u663E\u793A\u4E00\u4E2A\u5DE5\u5177)",
|
|
2524
2580
|
"cli.server.planShape": "plan \u9700\u8981 ActionPlan \u5BF9\u8C61(\u7531 /api/action/plan \u4EA7\u51FA)",
|
|
2525
2581
|
"cli.server.fixturesProtocol": "fixtures \u6A21\u5F0F\u53EA\u8BFB:\u4E0D\u9884\u89C8\u6216\u5199\u5165\u7528\u6237\u7EA7\u534F\u8BAE",
|
|
2526
2582
|
"cli.server.dshUserUnsupported": "unsupported: dsh \u65E0\u7528\u6237\u7EA7\u6307\u4EE4\u6587\u4EF6\uFF0C\u8BF7\u6309\u9879\u76EE\u5B89\u88C5\u8BA1\u5212\u534F\u8BAE",
|
|
@@ -2542,7 +2598,9 @@ var init_server2 = __esm({
|
|
|
2542
2598
|
"cli.server.settingsFormat": "\u56DE\u8DF3\u8BBE\u7F6E\u65E0\u6CD5\u89E3\u6790\u6216\u7248\u672C\u672A\u77E5,\u62D2\u7EDD\u8986\u76D6;\u8BF7\u4EBA\u5DE5\u68C0\u67E5 settings.json",
|
|
2543
2599
|
"cli.server.settingsWrite": "\u56DE\u8DF3\u8BBE\u7F6E\u5907\u4EFD\u6216\u5199\u5165\u5931\u8D25,\u672A\u8986\u76D6\u8BBE\u7F6E;\u8BF7\u4EBA\u5DE5\u68C0\u67E5 settings.json",
|
|
2544
2600
|
"cli.server.localeInvalid": "locale \u53EA\u63A5\u53D7\u5DF2\u6CE8\u518C\u8BED\u8A00\u6807\u7B7E",
|
|
2545
|
-
"cli.server.settingsInvalid": "\u8BBE\u7F6E\u53EA\u63A5\u53D7\u5DF2\u6CE8\u518C\u7684 locale
|
|
2601
|
+
"cli.server.settingsInvalid": "\u8BBE\u7F6E\u53EA\u63A5\u53D7\u5DF2\u6CE8\u518C\u7684 locale\u3001\u5408\u6CD5\u7684 island \u4F4D\u7F6E\u4E0E\u5927\u5C0F\u6216\u5DF2\u77E5\u7684 freeHarness",
|
|
2602
|
+
"cli.server.freeHarnessNotDetected": "\u5C1A\u672A\u63A2\u6D4B\u5230\u8FD9\u4E2A\u5DE5\u5177\uFF0C\u4E0D\u80FD\u8BBE\u4E3A\u514D\u8D39\u5DE5\u5177\u3002",
|
|
2603
|
+
"cli.server.freeHarnessCooldown": "\u514D\u8D39\u5DE5\u5177\u9009\u5B9A\u540E 7 \u5929\u5185\u4E0D\u80FD\u66F4\u6362\uFF0C\u53EF\u4E8E {switchableAt} \u66F4\u6362\u3002",
|
|
2546
2604
|
"cli.server.fixturesSettings": "fixtures \u6A21\u5F0F\u53EA\u8BFB:\u4E0D\u4FDD\u5B58\u8BED\u8A00\u8BBE\u7F6E",
|
|
2547
2605
|
"cli.server.settingsHome": "\u8BED\u8A00\u8BBE\u7F6E\u7F3A\u5C11 homeDir"
|
|
2548
2606
|
};
|
|
@@ -12241,11 +12299,12 @@ function recordWalkError(error, stats) {
|
|
|
12241
12299
|
if (stats && (code === void 0 || !TOLERATED_CODES.has(code)))
|
|
12242
12300
|
stats.unknownErrors += 1;
|
|
12243
12301
|
}
|
|
12244
|
-
function safeReaddir(dir, stats) {
|
|
12302
|
+
function safeReaddir(dir, stats, onError) {
|
|
12245
12303
|
try {
|
|
12246
12304
|
return readdirSync(dir, { withFileTypes: true });
|
|
12247
12305
|
} catch (e) {
|
|
12248
12306
|
recordWalkError(e, stats);
|
|
12307
|
+
onError?.(e);
|
|
12249
12308
|
return [];
|
|
12250
12309
|
}
|
|
12251
12310
|
}
|
|
@@ -13828,6 +13887,104 @@ var init_hooks2 = __esm({
|
|
|
13828
13887
|
}
|
|
13829
13888
|
});
|
|
13830
13889
|
|
|
13890
|
+
// packages/adapter-cc/dist/discover.js
|
|
13891
|
+
import { createReadStream, statSync as statSync3 } from "node:fs";
|
|
13892
|
+
import { join as join15 } from "node:path";
|
|
13893
|
+
import { createInterface } from "node:readline";
|
|
13894
|
+
async function readCwd(transcriptPath) {
|
|
13895
|
+
const input = createReadStream(transcriptPath, { encoding: "utf8", highWaterMark: 4096 });
|
|
13896
|
+
const lines2 = createInterface({ input, crlfDelay: Infinity });
|
|
13897
|
+
let count = 0;
|
|
13898
|
+
try {
|
|
13899
|
+
for await (const line of lines2) {
|
|
13900
|
+
count += 1;
|
|
13901
|
+
if (line.trim()) {
|
|
13902
|
+
const row = JSON.parse(line);
|
|
13903
|
+
if (typeof row?.cwd === "string" && row.cwd.length > 0)
|
|
13904
|
+
return row.cwd;
|
|
13905
|
+
}
|
|
13906
|
+
if (count >= 200)
|
|
13907
|
+
break;
|
|
13908
|
+
}
|
|
13909
|
+
throw new Error("Session cwd not found");
|
|
13910
|
+
} finally {
|
|
13911
|
+
lines2.close();
|
|
13912
|
+
input.destroy();
|
|
13913
|
+
}
|
|
13914
|
+
}
|
|
13915
|
+
async function discoverRecentSessions(homeDir, { now, windowMs, limit }, stats = newWalkStats()) {
|
|
13916
|
+
if (limit <= 0)
|
|
13917
|
+
return [];
|
|
13918
|
+
const candidates = [];
|
|
13919
|
+
const root = join15(homeDir, ".claude", "projects");
|
|
13920
|
+
let skipped = 0;
|
|
13921
|
+
const recordSkippedDirectory = () => {
|
|
13922
|
+
skipped += 1;
|
|
13923
|
+
};
|
|
13924
|
+
const rootEntries = safeReaddir(root, stats, (error) => {
|
|
13925
|
+
if (error.code !== "ENOENT")
|
|
13926
|
+
recordSkippedDirectory();
|
|
13927
|
+
});
|
|
13928
|
+
for (const entry of rootEntries) {
|
|
13929
|
+
if (stats.entriesLeft <= 0) {
|
|
13930
|
+
stats.truncated = true;
|
|
13931
|
+
break;
|
|
13932
|
+
}
|
|
13933
|
+
stats.entriesLeft -= 1;
|
|
13934
|
+
if (!entry.isDirectory())
|
|
13935
|
+
continue;
|
|
13936
|
+
const dir = join15(root, entry.name);
|
|
13937
|
+
for (const file of safeReaddir(dir, stats, recordSkippedDirectory)) {
|
|
13938
|
+
if (stats.entriesLeft <= 0) {
|
|
13939
|
+
stats.truncated = true;
|
|
13940
|
+
break;
|
|
13941
|
+
}
|
|
13942
|
+
stats.entriesLeft -= 1;
|
|
13943
|
+
if (!file.isFile() || !file.name.endsWith(".jsonl"))
|
|
13944
|
+
continue;
|
|
13945
|
+
const transcriptPath = join15(dir, file.name);
|
|
13946
|
+
try {
|
|
13947
|
+
const mtime = statSync3(transcriptPath).mtimeMs;
|
|
13948
|
+
if (mtime < now - windowMs || mtime > now)
|
|
13949
|
+
continue;
|
|
13950
|
+
const id = file.name.slice(0, -".jsonl".length);
|
|
13951
|
+
if (!id)
|
|
13952
|
+
throw new Error("Session id not found");
|
|
13953
|
+
candidates.push({ id, transcriptPath, mtime });
|
|
13954
|
+
} catch (error) {
|
|
13955
|
+
recordWalkError(error, stats);
|
|
13956
|
+
skipped += 1;
|
|
13957
|
+
}
|
|
13958
|
+
}
|
|
13959
|
+
if (stats.truncated)
|
|
13960
|
+
break;
|
|
13961
|
+
}
|
|
13962
|
+
candidates.sort((a, b) => b.mtime - a.mtime || a.transcriptPath.localeCompare(b.transcriptPath));
|
|
13963
|
+
const sessions = [];
|
|
13964
|
+
for (const candidate of candidates) {
|
|
13965
|
+
try {
|
|
13966
|
+
const cwd = await readCwd(candidate.transcriptPath);
|
|
13967
|
+
sessions.push({ ...candidate, cwd });
|
|
13968
|
+
if (sessions.length >= limit)
|
|
13969
|
+
break;
|
|
13970
|
+
} catch (error) {
|
|
13971
|
+
recordWalkError(error, stats);
|
|
13972
|
+
skipped += 1;
|
|
13973
|
+
}
|
|
13974
|
+
}
|
|
13975
|
+
if (skipped > 0) {
|
|
13976
|
+
process.stderr.write(`[wingman] cc startup discovery: skipped ${skipped} unreadable or invalid entries.
|
|
13977
|
+
`);
|
|
13978
|
+
}
|
|
13979
|
+
return sessions;
|
|
13980
|
+
}
|
|
13981
|
+
var init_discover = __esm({
|
|
13982
|
+
"packages/adapter-cc/dist/discover.js"() {
|
|
13983
|
+
"use strict";
|
|
13984
|
+
init_walk();
|
|
13985
|
+
}
|
|
13986
|
+
});
|
|
13987
|
+
|
|
13831
13988
|
// packages/adapter-cc/dist/generic-waiting.js
|
|
13832
13989
|
var GENERIC_WAITING_MESSAGES;
|
|
13833
13990
|
var init_generic_waiting = __esm({
|
|
@@ -13857,7 +14014,7 @@ var init_mcp_tools = __esm({
|
|
|
13857
14014
|
// packages/adapter-cc/dist/protocol.js
|
|
13858
14015
|
import { existsSync as existsSync10, mkdirSync as mkdirSync6, readdirSync as readdirSync3, readFileSync as readFileSync10, rmdirSync, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
13859
14016
|
import { homedir as homedir10 } from "node:os";
|
|
13860
|
-
import { basename as basename7, dirname as dirname10, join as
|
|
14017
|
+
import { basename as basename7, dirname as dirname10, join as join16, resolve as resolve6 } from "node:path";
|
|
13861
14018
|
function protocolStatusCc(options) {
|
|
13862
14019
|
const paths3 = resolveOptions2(options);
|
|
13863
14020
|
if (!existsSync10(paths3.targetPath)) {
|
|
@@ -13887,7 +14044,7 @@ function installProtocolCc(options) {
|
|
|
13887
14044
|
const backupDir = nextBackupDir3(paths3.homeDir);
|
|
13888
14045
|
const installedSha256 = sha256Hex(PLAN_PROTOCOL_TEXT);
|
|
13889
14046
|
if (!paths3.dryRun) {
|
|
13890
|
-
const claudeDir =
|
|
14047
|
+
const claudeDir = join16(paths3.projectDir, ".claude");
|
|
13891
14048
|
const rulesDir = dirname10(paths3.targetPath);
|
|
13892
14049
|
const prior = readState4(paths3.statePath);
|
|
13893
14050
|
backupTarget3(backupDir, paths3.targetPath, existing?.bytes);
|
|
@@ -13952,14 +14109,14 @@ function uninstallProtocolCc(options) {
|
|
|
13952
14109
|
function resolveOptions2(options) {
|
|
13953
14110
|
const homeDir = resolve6(options?.homeDir ?? homedir10());
|
|
13954
14111
|
const projectDir = resolve6(options?.projectDir ?? process.cwd());
|
|
13955
|
-
const targetPath2 =
|
|
14112
|
+
const targetPath2 = join16(projectDir, ".claude", "rules", "wingman-plan-protocol.md");
|
|
13956
14113
|
const projectHash = sha256Hex(projectDir);
|
|
13957
14114
|
return {
|
|
13958
14115
|
homeDir,
|
|
13959
14116
|
projectDir,
|
|
13960
14117
|
dryRun: options?.dryRun ?? false,
|
|
13961
14118
|
targetPath: targetPath2,
|
|
13962
|
-
statePath:
|
|
14119
|
+
statePath: join16(homeDir, ".wingman", "state", `plan-protocol-cc-${projectHash}.json`)
|
|
13963
14120
|
};
|
|
13964
14121
|
}
|
|
13965
14122
|
function readExisting(targetPath2) {
|
|
@@ -14011,16 +14168,16 @@ function modifiedError2(targetPath2, operation) {
|
|
|
14011
14168
|
}
|
|
14012
14169
|
function nextBackupDir3(homeDir) {
|
|
14013
14170
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
14014
|
-
const root =
|
|
14015
|
-
let dir =
|
|
14171
|
+
const root = join16(homeDir, ".wingman", "backups");
|
|
14172
|
+
let dir = join16(root, stamp);
|
|
14016
14173
|
for (let n = 2; existsSync10(dir); n += 1)
|
|
14017
|
-
dir =
|
|
14174
|
+
dir = join16(root, `${stamp}-${n}`);
|
|
14018
14175
|
return dir;
|
|
14019
14176
|
}
|
|
14020
14177
|
function backupTarget3(backupDir, targetPath2, bytes) {
|
|
14021
14178
|
mkdirSync6(backupDir, { recursive: true });
|
|
14022
14179
|
if (bytes !== void 0)
|
|
14023
|
-
writeFileSync7(
|
|
14180
|
+
writeFileSync7(join16(backupDir, basename7(targetPath2)), bytes);
|
|
14024
14181
|
}
|
|
14025
14182
|
function readState4(statePath2) {
|
|
14026
14183
|
if (!existsSync10(statePath2))
|
|
@@ -14062,12 +14219,12 @@ var init_protocol2 = __esm({
|
|
|
14062
14219
|
|
|
14063
14220
|
// packages/adapter-cc/dist/protocol-user.js
|
|
14064
14221
|
import { homedir as homedir11 } from "node:os";
|
|
14065
|
-
import { join as
|
|
14222
|
+
import { join as join17, resolve as resolve7 } from "node:path";
|
|
14066
14223
|
function paths(options) {
|
|
14067
14224
|
const homeDir = resolve7(options?.homeDir ?? homedir11());
|
|
14068
14225
|
return {
|
|
14069
14226
|
homeDir,
|
|
14070
|
-
targetPath:
|
|
14227
|
+
targetPath: join17(homeDir, ".claude", "CLAUDE.md"),
|
|
14071
14228
|
dryRun: options?.dryRun ?? false
|
|
14072
14229
|
};
|
|
14073
14230
|
}
|
|
@@ -14093,6 +14250,7 @@ __export(dist_exports2, {
|
|
|
14093
14250
|
GENERIC_WAITING_MESSAGES: () => GENERIC_WAITING_MESSAGES,
|
|
14094
14251
|
WIRED_EVENTS: () => WIRED_EVENTS,
|
|
14095
14252
|
createAdapter: () => createAdapter2,
|
|
14253
|
+
discoverRecentSessions: () => discoverRecentSessions,
|
|
14096
14254
|
feedbackSignals: () => feedbackSignalsCc,
|
|
14097
14255
|
installProtocolCc: () => installProtocolCc,
|
|
14098
14256
|
installProtocolCcUser: () => installProtocolCcUser,
|
|
@@ -14120,6 +14278,7 @@ var init_dist4 = __esm({
|
|
|
14120
14278
|
init_detect();
|
|
14121
14279
|
init_hooks2();
|
|
14122
14280
|
init_scan();
|
|
14281
|
+
init_discover();
|
|
14123
14282
|
init_generic_waiting();
|
|
14124
14283
|
init_hooks2();
|
|
14125
14284
|
init_mcp_tools();
|
|
@@ -14839,14 +14998,14 @@ var init_dist5 = __esm({
|
|
|
14839
14998
|
|
|
14840
14999
|
// packages/adapter-codex/dist/shared.js
|
|
14841
15000
|
import { homedir as homedir12 } from "node:os";
|
|
14842
|
-
import { join as
|
|
15001
|
+
import { join as join18 } from "node:path";
|
|
14843
15002
|
function resolvePaths(options) {
|
|
14844
15003
|
const homeDir = options?.homeDir ?? homedir12();
|
|
14845
15004
|
const projectDir = options?.projectDir ?? process.cwd();
|
|
14846
|
-
return { homeDir, projectDir, codexHome:
|
|
15005
|
+
return { homeDir, projectDir, codexHome: join18(homeDir, ".codex") };
|
|
14847
15006
|
}
|
|
14848
15007
|
function wingmanStateRoot(paths3) {
|
|
14849
|
-
return
|
|
15008
|
+
return join18(paths3.homeDir, ".wingman");
|
|
14850
15009
|
}
|
|
14851
15010
|
function isTable(value) {
|
|
14852
15011
|
return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
|
|
@@ -15155,8 +15314,8 @@ var init_toml_edit = __esm({
|
|
|
15155
15314
|
});
|
|
15156
15315
|
|
|
15157
15316
|
// packages/adapter-codex/dist/actions.js
|
|
15158
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync7, readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as
|
|
15159
|
-
import { basename as basename8, dirname as dirname11, join as
|
|
15317
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync7, readdirSync as readdirSync4, readFileSync as readFileSync11, statSync as statSync4, writeFileSync as writeFileSync8 } from "node:fs";
|
|
15318
|
+
import { basename as basename8, dirname as dirname11, join as join19 } from "node:path";
|
|
15160
15319
|
async function planAction(action, options) {
|
|
15161
15320
|
const paths3 = resolvePaths(options);
|
|
15162
15321
|
const resolved = resolveToggle(action, paths3);
|
|
@@ -15190,7 +15349,7 @@ async function applyAction(plan, options) {
|
|
|
15190
15349
|
error: t("adapter.codex.actions.planWritesDoesNotMatchThisAdapterSFormat")
|
|
15191
15350
|
};
|
|
15192
15351
|
}
|
|
15193
|
-
const backupsRoot =
|
|
15352
|
+
const backupsRoot = join19(wingmanStateRoot(paths3), "backups");
|
|
15194
15353
|
if (dirname11(plan.backupDir) !== backupsRoot) {
|
|
15195
15354
|
return {
|
|
15196
15355
|
ok: false,
|
|
@@ -15219,7 +15378,7 @@ async function applyAction(plan, options) {
|
|
|
15219
15378
|
};
|
|
15220
15379
|
}
|
|
15221
15380
|
mkdirSync7(plan.backupDir, { recursive: true });
|
|
15222
|
-
writeFileSync8(
|
|
15381
|
+
writeFileSync8(join19(plan.backupDir, basename8(write.file)), currentRaw);
|
|
15223
15382
|
writeFileSync8(write.file, write.after);
|
|
15224
15383
|
return { ok: true, backupDir: plan.backupDir };
|
|
15225
15384
|
} catch (error) {
|
|
@@ -15228,10 +15387,10 @@ async function applyAction(plan, options) {
|
|
|
15228
15387
|
}
|
|
15229
15388
|
function nextBackupDir4(paths3) {
|
|
15230
15389
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
15231
|
-
const base =
|
|
15232
|
-
let dir =
|
|
15390
|
+
const base = join19(wingmanStateRoot(paths3), "backups");
|
|
15391
|
+
let dir = join19(base, stamp);
|
|
15233
15392
|
for (let n = 1; existsSync11(dir); n += 1)
|
|
15234
|
-
dir =
|
|
15393
|
+
dir = join19(base, `${stamp}-${n}`);
|
|
15235
15394
|
return dir;
|
|
15236
15395
|
}
|
|
15237
15396
|
function resolveToggle(action, paths3) {
|
|
@@ -15249,7 +15408,7 @@ function resolveToggle(action, paths3) {
|
|
|
15249
15408
|
const slot = m[1];
|
|
15250
15409
|
const source = m[2];
|
|
15251
15410
|
const nativeName = m[3];
|
|
15252
|
-
const file = source === "user" ?
|
|
15411
|
+
const file = source === "user" ? join19(paths3.codexHome, "config.toml") : join19(paths3.projectDir, ".codex", "config.toml");
|
|
15253
15412
|
if (!existsSync11(file))
|
|
15254
15413
|
throw new Error(t("adapter.codex.actions.itemidNotFoundConfigurationFileDoesNotExist", { p0: String(file) }));
|
|
15255
15414
|
const before = readFileSync11(file, "utf8");
|
|
@@ -15527,18 +15686,18 @@ function verifyEdit(table, edit, file) {
|
|
|
15527
15686
|
}
|
|
15528
15687
|
function collectCorpus(paths3) {
|
|
15529
15688
|
const candidates = [
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
|
|
15536
|
-
...listFilesRecursive(
|
|
15689
|
+
join19(paths3.codexHome, "AGENTS.md"),
|
|
15690
|
+
join19(paths3.projectDir, "AGENTS.md"),
|
|
15691
|
+
join19(paths3.codexHome, "config.toml"),
|
|
15692
|
+
join19(paths3.projectDir, ".codex", "config.toml"),
|
|
15693
|
+
join19(paths3.codexHome, "hooks.json"),
|
|
15694
|
+
join19(paths3.projectDir, ".codex", "hooks.json"),
|
|
15695
|
+
...listFilesRecursive(join19(paths3.codexHome, "prompts"))
|
|
15537
15696
|
];
|
|
15538
15697
|
const sources = [];
|
|
15539
15698
|
for (const file of candidates) {
|
|
15540
15699
|
try {
|
|
15541
|
-
if (!
|
|
15700
|
+
if (!statSync4(file).isFile())
|
|
15542
15701
|
continue;
|
|
15543
15702
|
} catch {
|
|
15544
15703
|
continue;
|
|
@@ -15556,7 +15715,7 @@ function listFilesRecursive(dir) {
|
|
|
15556
15715
|
}
|
|
15557
15716
|
const files = [];
|
|
15558
15717
|
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
15559
|
-
const path =
|
|
15718
|
+
const path = join19(dir, entry.name);
|
|
15560
15719
|
if (entry.isDirectory())
|
|
15561
15720
|
files.push(...listFilesRecursive(path));
|
|
15562
15721
|
else if (entry.isFile())
|
|
@@ -15638,15 +15797,15 @@ var init_actions2 = __esm({
|
|
|
15638
15797
|
// packages/adapter-codex/dist/hooks.js
|
|
15639
15798
|
import { spawnSync } from "node:child_process";
|
|
15640
15799
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync12, realpathSync, rmSync as rmSync6, writeFileSync as writeFileSync9 } from "node:fs";
|
|
15641
|
-
import { basename as basename9, dirname as dirname12, join as
|
|
15800
|
+
import { basename as basename9, dirname as dirname12, join as join20 } from "node:path";
|
|
15642
15801
|
async function installHooks(port, options) {
|
|
15643
15802
|
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
15644
15803
|
throw new Error(t("adapter.codex.hooks.invalidPort", { p0: String(port) }));
|
|
15645
15804
|
}
|
|
15646
15805
|
const paths3 = resolvePaths(options);
|
|
15647
15806
|
const root = wingmanStateRoot(paths3);
|
|
15648
|
-
const scriptPath =
|
|
15649
|
-
const configPath =
|
|
15807
|
+
const scriptPath = join20(root, FORWARD_SCRIPT_NAME);
|
|
15808
|
+
const configPath = join20(paths3.codexHome, "config.toml");
|
|
15650
15809
|
const raw = existsSync12(configPath) ? readFileSync12(configPath) : void 0;
|
|
15651
15810
|
const text = raw?.toString("utf8") ?? "";
|
|
15652
15811
|
const { before, after, remainder, block } = splitManagedBlock(text, configPath);
|
|
@@ -15710,9 +15869,9 @@ async function installHooks(port, options) {
|
|
|
15710
15869
|
async function uninstallHooks(options) {
|
|
15711
15870
|
const paths3 = resolvePaths(options);
|
|
15712
15871
|
const root = wingmanStateRoot(paths3);
|
|
15713
|
-
const scriptPath =
|
|
15872
|
+
const scriptPath = join20(root, FORWARD_SCRIPT_NAME);
|
|
15714
15873
|
const statePath2 = hooksStatePath(root);
|
|
15715
|
-
const configPath =
|
|
15874
|
+
const configPath = join20(paths3.codexHome, "config.toml");
|
|
15716
15875
|
const state = readState5(statePath2);
|
|
15717
15876
|
const raw = existsSync12(configPath) ? readFileSync12(configPath) : void 0;
|
|
15718
15877
|
if (raw !== void 0) {
|
|
@@ -15738,25 +15897,25 @@ async function uninstallHooks(options) {
|
|
|
15738
15897
|
rmSync6(statePath2, { force: true });
|
|
15739
15898
|
}
|
|
15740
15899
|
function hasManagedHooks2(paths3) {
|
|
15741
|
-
const configPath =
|
|
15900
|
+
const configPath = join20(paths3.codexHome, "config.toml");
|
|
15742
15901
|
if (!existsSync12(configPath))
|
|
15743
15902
|
return false;
|
|
15744
15903
|
try {
|
|
15745
15904
|
const { block } = splitManagedBlock(readFileSync12(configPath, "utf8"), configPath);
|
|
15746
|
-
return block !== void 0 && inspectManagedBlock(block,
|
|
15905
|
+
return block !== void 0 && inspectManagedBlock(block, join20(wingmanStateRoot(paths3), FORWARD_SCRIPT_NAME)) !== void 0;
|
|
15747
15906
|
} catch {
|
|
15748
15907
|
return false;
|
|
15749
15908
|
}
|
|
15750
15909
|
}
|
|
15751
15910
|
function feedbackSignalsCodex(options) {
|
|
15752
15911
|
const paths3 = resolvePaths(options);
|
|
15753
|
-
const configPath =
|
|
15912
|
+
const configPath = join20(paths3.codexHome, "config.toml");
|
|
15754
15913
|
const wiredEvents = [];
|
|
15755
15914
|
if (existsSync12(configPath)) {
|
|
15756
15915
|
try {
|
|
15757
15916
|
const { block } = splitManagedBlock(readFileSync12(configPath, "utf8"), configPath);
|
|
15758
15917
|
if (block !== void 0) {
|
|
15759
|
-
const knownBlock = inspectManagedBlock(block,
|
|
15918
|
+
const knownBlock = inspectManagedBlock(block, join20(wingmanStateRoot(paths3), FORWARD_SCRIPT_NAME));
|
|
15760
15919
|
const hooks = knownBlock === void 0 ? void 0 : parse3(normalizeLineEndings(knownBlock.managedBlock)).hooks;
|
|
15761
15920
|
if (isTable(hooks)) {
|
|
15762
15921
|
for (const [event, groups] of Object.entries(hooks)) {
|
|
@@ -16013,15 +16172,15 @@ function hasHooksState(text) {
|
|
|
16013
16172
|
}
|
|
16014
16173
|
function backupFile(root, filePath, contents) {
|
|
16015
16174
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
16016
|
-
let dir =
|
|
16175
|
+
let dir = join20(root, "backups", stamp);
|
|
16017
16176
|
for (let n = 1; existsSync12(dir); n += 1)
|
|
16018
|
-
dir =
|
|
16177
|
+
dir = join20(root, "backups", `${stamp}-${n}`);
|
|
16019
16178
|
mkdirSync8(dir, { recursive: true });
|
|
16020
|
-
writeFileSync9(
|
|
16179
|
+
writeFileSync9(join20(dir, basename9(filePath)), contents);
|
|
16021
16180
|
return dir;
|
|
16022
16181
|
}
|
|
16023
16182
|
function hooksStatePath(root) {
|
|
16024
|
-
return
|
|
16183
|
+
return join20(root, "state", "codex-hooks.json");
|
|
16025
16184
|
}
|
|
16026
16185
|
function readState5(statePath2) {
|
|
16027
16186
|
if (!existsSync12(statePath2))
|
|
@@ -16191,11 +16350,11 @@ process.stdin.on('end', async () => {
|
|
|
16191
16350
|
});
|
|
16192
16351
|
|
|
16193
16352
|
// packages/adapter-codex/dist/scan.js
|
|
16194
|
-
import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync13, realpathSync as realpathSync2, statSync as
|
|
16195
|
-
import { dirname as dirname13, isAbsolute as isAbsolute3, join as
|
|
16353
|
+
import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync13, realpathSync as realpathSync2, statSync as statSync5 } from "node:fs";
|
|
16354
|
+
import { dirname as dirname13, isAbsolute as isAbsolute3, join as join21, resolve as resolve8 } from "node:path";
|
|
16196
16355
|
function readCodexProjects(homeDir) {
|
|
16197
16356
|
try {
|
|
16198
|
-
const state = JSON.parse(readFileSync13(
|
|
16357
|
+
const state = JSON.parse(readFileSync13(join21(homeDir, ".codex", ".codex-global-state.json"), "utf8"));
|
|
16199
16358
|
if (!isTable(state))
|
|
16200
16359
|
return void 0;
|
|
16201
16360
|
const localProjects = state["local-projects"];
|
|
@@ -16272,8 +16431,8 @@ async function scan(options) {
|
|
|
16272
16431
|
}
|
|
16273
16432
|
function loadConfigLayers(paths3) {
|
|
16274
16433
|
const candidates = [
|
|
16275
|
-
["user",
|
|
16276
|
-
["project",
|
|
16434
|
+
["user", join21(paths3.codexHome, "config.toml")],
|
|
16435
|
+
["project", join21(paths3.projectDir, ".codex", "config.toml")]
|
|
16277
16436
|
];
|
|
16278
16437
|
const layers = [];
|
|
16279
16438
|
for (const [source, path] of candidates) {
|
|
@@ -16290,8 +16449,8 @@ function loadConfigLayers(paths3) {
|
|
|
16290
16449
|
}
|
|
16291
16450
|
function collectRules(out, paths3, layers) {
|
|
16292
16451
|
const agentsChain = [
|
|
16293
|
-
["user",
|
|
16294
|
-
["project",
|
|
16452
|
+
["user", join21(paths3.codexHome, "AGENTS.md")],
|
|
16453
|
+
["project", join21(paths3.projectDir, "AGENTS.md")]
|
|
16295
16454
|
];
|
|
16296
16455
|
for (const [source, file] of agentsChain) {
|
|
16297
16456
|
const size = fileSize(file);
|
|
@@ -16426,7 +16585,7 @@ function collectGates(out, layer) {
|
|
|
16426
16585
|
}
|
|
16427
16586
|
}
|
|
16428
16587
|
function collectHistory(out, paths3, layers) {
|
|
16429
|
-
const historyFile =
|
|
16588
|
+
const historyFile = join21(paths3.codexHome, "history.jsonl");
|
|
16430
16589
|
const historyBytes = fileSize(historyFile);
|
|
16431
16590
|
if (historyBytes !== void 0) {
|
|
16432
16591
|
out.push({
|
|
@@ -16441,7 +16600,7 @@ function collectHistory(out, paths3, layers) {
|
|
|
16441
16600
|
});
|
|
16442
16601
|
}
|
|
16443
16602
|
const configured = layers.find((layer) => layer.source === "user")?.table.log_dir;
|
|
16444
|
-
const logDir = typeof configured === "string" ? expandPath(configured, paths3) :
|
|
16603
|
+
const logDir = typeof configured === "string" ? expandPath(configured, paths3) : join21(paths3.codexHome, "log");
|
|
16445
16604
|
if (isDirectory(logDir)) {
|
|
16446
16605
|
out.push({
|
|
16447
16606
|
id: "codex:history:user:log_dir",
|
|
@@ -16457,7 +16616,7 @@ function collectHistory(out, paths3, layers) {
|
|
|
16457
16616
|
}
|
|
16458
16617
|
function expandPath(value, paths3) {
|
|
16459
16618
|
if (value === "~" || value.startsWith("~/"))
|
|
16460
|
-
return
|
|
16619
|
+
return join21(paths3.homeDir, value.slice(2));
|
|
16461
16620
|
return isAbsolute3(value) ? value : resolve8(paths3.codexHome, value);
|
|
16462
16621
|
}
|
|
16463
16622
|
function assertUniqueIds(slots) {
|
|
@@ -16473,7 +16632,7 @@ function assertUniqueIds(slots) {
|
|
|
16473
16632
|
}
|
|
16474
16633
|
function fileSize(path) {
|
|
16475
16634
|
try {
|
|
16476
|
-
const stats =
|
|
16635
|
+
const stats = statSync5(path);
|
|
16477
16636
|
return stats.isFile() ? stats.size : void 0;
|
|
16478
16637
|
} catch {
|
|
16479
16638
|
return void 0;
|
|
@@ -16481,7 +16640,7 @@ function fileSize(path) {
|
|
|
16481
16640
|
}
|
|
16482
16641
|
function isDirectory(path) {
|
|
16483
16642
|
try {
|
|
16484
|
-
return
|
|
16643
|
+
return statSync5(path).isDirectory();
|
|
16485
16644
|
} catch {
|
|
16486
16645
|
return false;
|
|
16487
16646
|
}
|
|
@@ -16489,11 +16648,11 @@ function isDirectory(path) {
|
|
|
16489
16648
|
function directoryBytes(dir) {
|
|
16490
16649
|
let total = 0;
|
|
16491
16650
|
for (const entry of readdirSync5(dir, { withFileTypes: true })) {
|
|
16492
|
-
const entryPath =
|
|
16651
|
+
const entryPath = join21(dir, entry.name);
|
|
16493
16652
|
if (entry.isDirectory())
|
|
16494
16653
|
total += directoryBytes(entryPath);
|
|
16495
16654
|
else if (entry.isFile())
|
|
16496
|
-
total +=
|
|
16655
|
+
total += statSync5(entryPath).size;
|
|
16497
16656
|
}
|
|
16498
16657
|
return total;
|
|
16499
16658
|
}
|
|
@@ -16510,6 +16669,128 @@ var init_scan2 = __esm({
|
|
|
16510
16669
|
}
|
|
16511
16670
|
});
|
|
16512
16671
|
|
|
16672
|
+
// packages/adapter-codex/dist/discover.js
|
|
16673
|
+
import { createReadStream as createReadStream2, readdirSync as readdirSync6, statSync as statSync6 } from "node:fs";
|
|
16674
|
+
import { join as join22 } from "node:path";
|
|
16675
|
+
import { createInterface as createInterface2 } from "node:readline";
|
|
16676
|
+
function recordWalkError2(error, stats) {
|
|
16677
|
+
const code = error.code;
|
|
16678
|
+
if (code === void 0 || !TOLERATED_CODES2.has(code))
|
|
16679
|
+
stats.unknownErrors += 1;
|
|
16680
|
+
}
|
|
16681
|
+
function safeReaddir2(dir, stats, onError) {
|
|
16682
|
+
try {
|
|
16683
|
+
return readdirSync6(dir, { withFileTypes: true });
|
|
16684
|
+
} catch (error) {
|
|
16685
|
+
recordWalkError2(error, stats);
|
|
16686
|
+
onError(error);
|
|
16687
|
+
return [];
|
|
16688
|
+
}
|
|
16689
|
+
}
|
|
16690
|
+
async function readMetadata(file) {
|
|
16691
|
+
const stream = createReadStream2(file, { encoding: "utf8", highWaterMark: 4096 });
|
|
16692
|
+
const lines2 = createInterface2({ input: stream, crlfDelay: Number.POSITIVE_INFINITY });
|
|
16693
|
+
let lineCount = 0;
|
|
16694
|
+
try {
|
|
16695
|
+
for await (const line of lines2) {
|
|
16696
|
+
lineCount += 1;
|
|
16697
|
+
if (line.trim()) {
|
|
16698
|
+
const row = JSON.parse(line);
|
|
16699
|
+
if (isTable(row) && row.type === "session_meta") {
|
|
16700
|
+
const payload = row.payload;
|
|
16701
|
+
if (!isTable(payload) || typeof payload.id !== "string" || !payload.id) {
|
|
16702
|
+
throw new Error("Invalid session metadata");
|
|
16703
|
+
}
|
|
16704
|
+
if (typeof payload.parent_thread_id === "string" && payload.parent_thread_id) {
|
|
16705
|
+
return void 0;
|
|
16706
|
+
}
|
|
16707
|
+
const result5 = { id: payload.id };
|
|
16708
|
+
if (typeof payload.cwd === "string" && payload.cwd)
|
|
16709
|
+
result5.cwd = payload.cwd;
|
|
16710
|
+
return result5;
|
|
16711
|
+
}
|
|
16712
|
+
}
|
|
16713
|
+
if (lineCount >= MAX_META_LINES)
|
|
16714
|
+
break;
|
|
16715
|
+
}
|
|
16716
|
+
throw new Error("No session metadata within the line limit");
|
|
16717
|
+
} finally {
|
|
16718
|
+
lines2.close();
|
|
16719
|
+
stream.destroy();
|
|
16720
|
+
}
|
|
16721
|
+
}
|
|
16722
|
+
async function discoverRecentSessions2(homeDir, { now, windowMs, limit }, stats = {
|
|
16723
|
+
unknownErrors: 0,
|
|
16724
|
+
truncated: false,
|
|
16725
|
+
entriesLeft: MAX_WALK_ENTRIES2
|
|
16726
|
+
}) {
|
|
16727
|
+
if (limit <= 0)
|
|
16728
|
+
return [];
|
|
16729
|
+
const candidates = [];
|
|
16730
|
+
let skipped = 0;
|
|
16731
|
+
const visit = (dir, depth) => {
|
|
16732
|
+
const entries = safeReaddir2(dir, stats, (error) => {
|
|
16733
|
+
if (depth !== 1 || error.code !== "ENOENT")
|
|
16734
|
+
skipped += 1;
|
|
16735
|
+
});
|
|
16736
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
16737
|
+
if (stats.entriesLeft <= 0) {
|
|
16738
|
+
stats.truncated = true;
|
|
16739
|
+
return;
|
|
16740
|
+
}
|
|
16741
|
+
stats.entriesLeft -= 1;
|
|
16742
|
+
const path = join22(dir, entry.name);
|
|
16743
|
+
if (entry.isDirectory()) {
|
|
16744
|
+
if (depth < MAX_WALK_DEPTH2 && !entry.name.startsWith("."))
|
|
16745
|
+
visit(path, depth + 1);
|
|
16746
|
+
if (stats.truncated)
|
|
16747
|
+
return;
|
|
16748
|
+
} else if (entry.isFile() && entry.name.startsWith("rollout-") && entry.name.endsWith(".jsonl")) {
|
|
16749
|
+
try {
|
|
16750
|
+
const mtime = statSync6(path).mtimeMs;
|
|
16751
|
+
if (mtime >= now - windowMs && mtime <= now) {
|
|
16752
|
+
candidates.push({ transcriptPath: path, mtime });
|
|
16753
|
+
}
|
|
16754
|
+
} catch (error) {
|
|
16755
|
+
recordWalkError2(error, stats);
|
|
16756
|
+
skipped += 1;
|
|
16757
|
+
}
|
|
16758
|
+
}
|
|
16759
|
+
}
|
|
16760
|
+
};
|
|
16761
|
+
visit(join22(homeDir, ".codex", "sessions"), 1);
|
|
16762
|
+
candidates.sort((a, b) => b.mtime - a.mtime);
|
|
16763
|
+
const sessions = [];
|
|
16764
|
+
for (const candidate of candidates) {
|
|
16765
|
+
try {
|
|
16766
|
+
const metadata = await readMetadata(candidate.transcriptPath);
|
|
16767
|
+
if (metadata)
|
|
16768
|
+
sessions.push({ ...metadata, ...candidate });
|
|
16769
|
+
} catch (error) {
|
|
16770
|
+
recordWalkError2(error, stats);
|
|
16771
|
+
skipped += 1;
|
|
16772
|
+
}
|
|
16773
|
+
if (sessions.length >= limit)
|
|
16774
|
+
break;
|
|
16775
|
+
}
|
|
16776
|
+
if (skipped > 0) {
|
|
16777
|
+
process.stderr.write(`[wingman] codex startup discovery: skipped ${skipped} unreadable or invalid entries.
|
|
16778
|
+
`);
|
|
16779
|
+
}
|
|
16780
|
+
return sessions;
|
|
16781
|
+
}
|
|
16782
|
+
var TOLERATED_CODES2, MAX_WALK_DEPTH2, MAX_WALK_ENTRIES2, MAX_META_LINES;
|
|
16783
|
+
var init_discover2 = __esm({
|
|
16784
|
+
"packages/adapter-codex/dist/discover.js"() {
|
|
16785
|
+
"use strict";
|
|
16786
|
+
init_shared();
|
|
16787
|
+
TOLERATED_CODES2 = /* @__PURE__ */ new Set(["EPERM", "EACCES", "ENOENT"]);
|
|
16788
|
+
MAX_WALK_DEPTH2 = 6;
|
|
16789
|
+
MAX_WALK_ENTRIES2 = 5e4;
|
|
16790
|
+
MAX_META_LINES = 200;
|
|
16791
|
+
}
|
|
16792
|
+
});
|
|
16793
|
+
|
|
16513
16794
|
// packages/adapter-codex/dist/plugin-tools.js
|
|
16514
16795
|
function recognizePluginTool(name, namespace, configuredPlugins) {
|
|
16515
16796
|
const fullName = name.startsWith("mcp__") ? name : namespace?.startsWith("mcp__") ? `${namespace}__${name}` : void 0;
|
|
@@ -16545,7 +16826,7 @@ var init_plugin_tools = __esm({
|
|
|
16545
16826
|
|
|
16546
16827
|
// packages/adapter-codex/dist/protocol.js
|
|
16547
16828
|
import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync14, rmSync as rmSync7, writeFileSync as writeFileSync10 } from "node:fs";
|
|
16548
|
-
import { basename as basename10, dirname as dirname14, join as
|
|
16829
|
+
import { basename as basename10, dirname as dirname14, join as join23, resolve as resolve9 } from "node:path";
|
|
16549
16830
|
function protocolStatusCodex(options) {
|
|
16550
16831
|
const paths3 = resolveOptions3(options);
|
|
16551
16832
|
if (!existsSync14(paths3.targetPath))
|
|
@@ -16641,8 +16922,8 @@ function resolveOptions3(options) {
|
|
|
16641
16922
|
const base = resolvePaths(options);
|
|
16642
16923
|
const homeDir = resolve9(base.homeDir);
|
|
16643
16924
|
const projectDir = resolve9(base.projectDir);
|
|
16644
|
-
const targetPath2 =
|
|
16645
|
-
const statePath2 =
|
|
16925
|
+
const targetPath2 = join23(projectDir, "AGENTS.md");
|
|
16926
|
+
const statePath2 = join23(wingmanStateRoot({ ...base, homeDir, projectDir }), "state", `plan-protocol-agents-${sha256Hex(projectDir)}.json`);
|
|
16646
16927
|
return { homeDir, projectDir, targetPath: targetPath2, statePath: statePath2, dryRun: options?.dryRun ?? false };
|
|
16647
16928
|
}
|
|
16648
16929
|
function readAgents2(targetPath2) {
|
|
@@ -16713,16 +16994,16 @@ function modifiedError3(targetPath2, operation) {
|
|
|
16713
16994
|
}
|
|
16714
16995
|
function nextBackupDir5(homeDir) {
|
|
16715
16996
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
16716
|
-
const root =
|
|
16717
|
-
let dir =
|
|
16997
|
+
const root = join23(homeDir, ".wingman", "backups");
|
|
16998
|
+
let dir = join23(root, stamp);
|
|
16718
16999
|
for (let n = 2; existsSync14(dir); n += 1)
|
|
16719
|
-
dir =
|
|
17000
|
+
dir = join23(root, `${stamp}-${n}`);
|
|
16720
17001
|
return dir;
|
|
16721
17002
|
}
|
|
16722
17003
|
function backupTarget4(backupDir, targetPath2, bytes) {
|
|
16723
17004
|
mkdirSync9(backupDir, { recursive: true });
|
|
16724
17005
|
if (bytes !== void 0)
|
|
16725
|
-
writeFileSync10(
|
|
17006
|
+
writeFileSync10(join23(backupDir, basename10(targetPath2)), bytes);
|
|
16726
17007
|
}
|
|
16727
17008
|
function readState6(statePath2, targetPath2) {
|
|
16728
17009
|
if (!existsSync14(statePath2))
|
|
@@ -16774,12 +17055,12 @@ var init_session_origin = __esm({
|
|
|
16774
17055
|
|
|
16775
17056
|
// packages/adapter-codex/dist/protocol-user.js
|
|
16776
17057
|
import { homedir as homedir13 } from "node:os";
|
|
16777
|
-
import { join as
|
|
17058
|
+
import { join as join24, resolve as resolve10 } from "node:path";
|
|
16778
17059
|
function paths2(options) {
|
|
16779
17060
|
const homeDir = resolve10(options?.homeDir ?? homedir13());
|
|
16780
17061
|
return {
|
|
16781
17062
|
homeDir,
|
|
16782
|
-
targetPath:
|
|
17063
|
+
targetPath: join24(homeDir, ".codex", "AGENTS.md"),
|
|
16783
17064
|
dryRun: options?.dryRun ?? false
|
|
16784
17065
|
};
|
|
16785
17066
|
}
|
|
@@ -16805,6 +17086,7 @@ __export(dist_exports3, {
|
|
|
16805
17086
|
HOOK_EVENTS: () => HOOK_EVENTS,
|
|
16806
17087
|
createAdapter: () => createAdapter3,
|
|
16807
17088
|
describeSessionOrigin: () => describeSessionOrigin,
|
|
17089
|
+
discoverRecentSessions: () => discoverRecentSessions2,
|
|
16808
17090
|
feedbackSignals: () => feedbackSignalsCodex,
|
|
16809
17091
|
installProtocolCodex: () => installProtocolCodex,
|
|
16810
17092
|
installProtocolCodexUser: () => installProtocolCodexUser,
|
|
@@ -16833,6 +17115,7 @@ var init_dist6 = __esm({
|
|
|
16833
17115
|
init_actions2();
|
|
16834
17116
|
init_hooks3();
|
|
16835
17117
|
init_scan2();
|
|
17118
|
+
init_discover2();
|
|
16836
17119
|
init_hooks3();
|
|
16837
17120
|
init_plugin_tools();
|
|
16838
17121
|
init_protocol3();
|
|
@@ -17263,9 +17546,9 @@ init_dist6();
|
|
|
17263
17546
|
init_dist3();
|
|
17264
17547
|
init_dist2();
|
|
17265
17548
|
init_dist();
|
|
17266
|
-
import { realpathSync as realpathSync3, statSync as
|
|
17549
|
+
import { realpathSync as realpathSync3, statSync as statSync8 } from "node:fs";
|
|
17267
17550
|
import { readdir as readdir2 } from "node:fs/promises";
|
|
17268
|
-
import { isAbsolute as isAbsolute6, join as
|
|
17551
|
+
import { isAbsolute as isAbsolute6, join as join28, relative as relative4, resolve as resolve12 } from "node:path";
|
|
17269
17552
|
|
|
17270
17553
|
// packages/narrative/dist/attribute.js
|
|
17271
17554
|
function extractSteps(lines2) {
|
|
@@ -17603,10 +17886,16 @@ function isRecord2(value) {
|
|
|
17603
17886
|
}
|
|
17604
17887
|
|
|
17605
17888
|
// packages/narrative/dist/parse.js
|
|
17889
|
+
var IMAGE_CAPTION_LINE = /^\s*\[Image: original \d+x\d+, displayed at \d+x\d+\.[^\]]*\]\s*$/u;
|
|
17890
|
+
function stripImageCaptions(body) {
|
|
17891
|
+
return body.split(/\r?\n/u).filter((line) => !IMAGE_CAPTION_LINE.test(line)).join("\n").trim();
|
|
17892
|
+
}
|
|
17606
17893
|
function userRequestText(text) {
|
|
17607
17894
|
let body = text.trim();
|
|
17608
17895
|
if (/^<(task-notification|system-reminder)\b/u.test(body))
|
|
17609
17896
|
return "";
|
|
17897
|
+
if (IMAGE_CAPTION_LINE.test(body.split(/\r?\n/u, 1)[0] ?? ""))
|
|
17898
|
+
body = stripImageCaptions(body);
|
|
17610
17899
|
let browserEnvelope = false;
|
|
17611
17900
|
if (/^<in-app-browser-context\b/u.test(body)) {
|
|
17612
17901
|
const end = body.indexOf("</in-app-browser-context>");
|
|
@@ -17628,6 +17917,9 @@ function userRequestText(text) {
|
|
|
17628
17917
|
function isHarnessSystemNotice(text) {
|
|
17629
17918
|
if (/^\s*<in-app-browser-context\b/u.test(text))
|
|
17630
17919
|
return userRequestText(text) === "";
|
|
17920
|
+
if (IMAGE_CAPTION_LINE.test(text.trim().split(/\r?\n/u, 1)[0] ?? "")) {
|
|
17921
|
+
return userRequestText(text) === "";
|
|
17922
|
+
}
|
|
17631
17923
|
return /^\s*<(task-notification|system-reminder|in-app-browser-context)\b/u.test(text);
|
|
17632
17924
|
}
|
|
17633
17925
|
function parseTranscriptLine(line) {
|
|
@@ -18875,7 +19167,7 @@ function isRecord5(value) {
|
|
|
18875
19167
|
// apps/cli/dist/project-index.js
|
|
18876
19168
|
init_dist();
|
|
18877
19169
|
import { lstat, readFile as readFile3, realpath, stat as stat3 } from "node:fs/promises";
|
|
18878
|
-
import { dirname as dirname15, isAbsolute as isAbsolute4, join as
|
|
19170
|
+
import { dirname as dirname15, isAbsolute as isAbsolute4, join as join25, relative as relative3, resolve as resolve11 } from "node:path";
|
|
18879
19171
|
var PROJECT_ROOT_MAX_DIRECTORIES = 8;
|
|
18880
19172
|
var PROJECT_PLAN_POLL_MS = 2e3;
|
|
18881
19173
|
async function resolveProjectRoot(cwd, options) {
|
|
@@ -18887,8 +19179,8 @@ async function resolveProjectRoot(cwd, options) {
|
|
|
18887
19179
|
pathIdentity(homeDir),
|
|
18888
19180
|
boundaryDir === void 0 ? void 0 : pathIdentity(boundaryDir)
|
|
18889
19181
|
]);
|
|
18890
|
-
const wingmanHomeIdentity = await pathIdentity(
|
|
18891
|
-
const planPathIdentity = await pathIdentity(
|
|
19182
|
+
const wingmanHomeIdentity = await pathIdentity(join25(homeIdentity, ".wingman"));
|
|
19183
|
+
const planPathIdentity = await pathIdentity(join25(rootIdentity, ".wingman", "plan.md"));
|
|
18892
19184
|
if (rootIdentity === homeIdentity || rootIdentity === wingmanHomeIdentity || boundaryIdentity !== void 0 && !isWithin(boundaryIdentity, rootIdentity)) {
|
|
18893
19185
|
return {
|
|
18894
19186
|
root,
|
|
@@ -18909,7 +19201,7 @@ async function resolveProjectRoot(cwd, options) {
|
|
|
18909
19201
|
break;
|
|
18910
19202
|
if (boundaryIdentity !== void 0 && !isWithin(boundaryIdentity, currentIdentity))
|
|
18911
19203
|
break;
|
|
18912
|
-
const planPath =
|
|
19204
|
+
const planPath = join25(current, ".wingman", "plan.md");
|
|
18913
19205
|
lookedUp.push(planPath);
|
|
18914
19206
|
try {
|
|
18915
19207
|
await lstat(planPath);
|
|
@@ -19025,11 +19317,11 @@ function isWithin(parent, child) {
|
|
|
19025
19317
|
// apps/cli/dist/project-roots.js
|
|
19026
19318
|
init_dist();
|
|
19027
19319
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
19028
|
-
import { closeSync, mkdirSync as mkdirSync10, openSync, readFileSync as readFileSync15, renameSync as renameSync3, rmSync as rmSync8, statSync as
|
|
19029
|
-
import { dirname as dirname16, isAbsolute as isAbsolute5, join as
|
|
19320
|
+
import { closeSync, mkdirSync as mkdirSync10, openSync, readFileSync as readFileSync15, renameSync as renameSync3, rmSync as rmSync8, statSync as statSync7, writeFileSync as writeFileSync11 } from "node:fs";
|
|
19321
|
+
import { dirname as dirname16, isAbsolute as isAbsolute5, join as join26 } from "node:path";
|
|
19030
19322
|
var PROJECT_ROOTS_MAX_ENTRIES = 200;
|
|
19031
19323
|
function projectRootsPath(homeDir) {
|
|
19032
|
-
return
|
|
19324
|
+
return join26(homeDir, ".wingman", "state", "projects.json");
|
|
19033
19325
|
}
|
|
19034
19326
|
function readProjectRoots(homeDir) {
|
|
19035
19327
|
const path = projectRootsPath(homeDir);
|
|
@@ -19089,7 +19381,7 @@ function pruneProjectRoots(homeDir) {
|
|
|
19089
19381
|
return current;
|
|
19090
19382
|
const roots = Object.fromEntries(Object.entries(current.roots).filter(([, entry]) => {
|
|
19091
19383
|
try {
|
|
19092
|
-
|
|
19384
|
+
statSync7(join26(entry.root, ".wingman", "plan.md"));
|
|
19093
19385
|
return true;
|
|
19094
19386
|
} catch (error) {
|
|
19095
19387
|
return !isErrno(error, "ENOENT") && !isErrno(error, "ENOTDIR");
|
|
@@ -19115,7 +19407,7 @@ function limitRoots(roots) {
|
|
|
19115
19407
|
}
|
|
19116
19408
|
function writeProjectRoots(homeDir, state) {
|
|
19117
19409
|
const path = projectRootsPath(homeDir);
|
|
19118
|
-
const tempPath =
|
|
19410
|
+
const tempPath = join26(dirname16(path), `.projects-${randomBytes2(8).toString("hex")}.tmp`);
|
|
19119
19411
|
let fd;
|
|
19120
19412
|
try {
|
|
19121
19413
|
mkdirSync10(dirname16(path), { recursive: true, mode: 448 });
|
|
@@ -19164,9 +19456,9 @@ function isErrno(error, code) {
|
|
|
19164
19456
|
init_dist();
|
|
19165
19457
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
19166
19458
|
import { closeSync as closeSync2, copyFileSync as copyFileSync2, mkdirSync as mkdirSync11, openSync as openSync2, readFileSync as readFileSync16, renameSync as renameSync4, rmSync as rmSync9, writeFileSync as writeFileSync12 } from "node:fs";
|
|
19167
|
-
import { dirname as dirname17, join as
|
|
19459
|
+
import { dirname as dirname17, join as join27 } from "node:path";
|
|
19168
19460
|
function taskOverlayPath(homeDir) {
|
|
19169
|
-
return
|
|
19461
|
+
return join27(homeDir, ".wingman", "state", "task-overlay.json");
|
|
19170
19462
|
}
|
|
19171
19463
|
function readTaskOverlay(homeDir) {
|
|
19172
19464
|
const path = taskOverlayPath(homeDir);
|
|
@@ -19289,7 +19581,7 @@ function patchProjectOverlay(homeDir, root, patch, now) {
|
|
|
19289
19581
|
}
|
|
19290
19582
|
function writeTaskOverlay(homeDir, overlay) {
|
|
19291
19583
|
const path = taskOverlayPath(homeDir);
|
|
19292
|
-
const tempPath =
|
|
19584
|
+
const tempPath = join27(dirname17(path), `.task-overlay-${randomBytes3(8).toString("hex")}.tmp`);
|
|
19293
19585
|
let fd;
|
|
19294
19586
|
try {
|
|
19295
19587
|
mkdirSync11(dirname17(path), { recursive: true, mode: 448 });
|
|
@@ -19370,7 +19662,7 @@ function resolveWingmanVersion({ defined, moduleUrl = import.meta.url, readPacka
|
|
|
19370
19662
|
return void 0;
|
|
19371
19663
|
}
|
|
19372
19664
|
function wingmanVersion() {
|
|
19373
|
-
const defined = false ? void 0 : "0.9.
|
|
19665
|
+
const defined = false ? void 0 : "0.9.6";
|
|
19374
19666
|
return resolveWingmanVersion({
|
|
19375
19667
|
defined,
|
|
19376
19668
|
readPackage: (url) => JSON.parse(readFileSync17(url, "utf8"))
|
|
@@ -19379,7 +19671,9 @@ function wingmanVersion() {
|
|
|
19379
19671
|
|
|
19380
19672
|
// apps/cli/dist/narrative-service.js
|
|
19381
19673
|
var MAX_SESSIONS = 8;
|
|
19674
|
+
var STARTUP_DISCOVERY_WINDOW_MS = 30 * 6e4;
|
|
19382
19675
|
var ENDED_AFTER_STOP_MS = 10 * 6e4;
|
|
19676
|
+
var WAIT_OUTCOME_TTL_MS = 8e3;
|
|
19383
19677
|
var DETAIL_LIMIT = 80;
|
|
19384
19678
|
var QUOTE_LIMIT = 160;
|
|
19385
19679
|
var ERROR_BRIEF_LIMIT = 60;
|
|
@@ -19429,7 +19723,7 @@ function createNarrativeService(options = {}) {
|
|
|
19429
19723
|
return;
|
|
19430
19724
|
let signature = "missing";
|
|
19431
19725
|
try {
|
|
19432
|
-
const info =
|
|
19726
|
+
const info = statSync8(join28(options.homeDir, ".codex", ".codex-global-state.json"));
|
|
19433
19727
|
signature = `${info.mtimeMs}:${info.ctimeMs}:${info.size}:${info.mode}`;
|
|
19434
19728
|
} catch {
|
|
19435
19729
|
}
|
|
@@ -19516,6 +19810,30 @@ function createNarrativeService(options = {}) {
|
|
|
19516
19810
|
if (session.subagentTimer !== void 0)
|
|
19517
19811
|
clearInterval(session.subagentTimer);
|
|
19518
19812
|
session.subagentTimer = void 0;
|
|
19813
|
+
clearWaitOutcome(session);
|
|
19814
|
+
}
|
|
19815
|
+
function clearWaitOutcome(session) {
|
|
19816
|
+
if (session.waitOutcomeTimer !== void 0)
|
|
19817
|
+
clearTimeout(session.waitOutcomeTimer);
|
|
19818
|
+
session.waitOutcomeTimer = void 0;
|
|
19819
|
+
session.waitOutcome = void 0;
|
|
19820
|
+
}
|
|
19821
|
+
function recordWaitOutcome(harness, session, waiting, outcome, source) {
|
|
19822
|
+
clearWaitOutcome(session);
|
|
19823
|
+
session.waitOutcome = {
|
|
19824
|
+
outcome,
|
|
19825
|
+
at: now().toISOString(),
|
|
19826
|
+
get message() {
|
|
19827
|
+
return waiting.message;
|
|
19828
|
+
},
|
|
19829
|
+
...waiting.messageI18n === void 0 ? {} : { messageI18n: waiting.messageI18n },
|
|
19830
|
+
source
|
|
19831
|
+
};
|
|
19832
|
+
session.waitOutcomeTimer = setTimeout(() => {
|
|
19833
|
+
session.waitOutcomeTimer = void 0;
|
|
19834
|
+
session.dirty = true;
|
|
19835
|
+
notify(harness);
|
|
19836
|
+
}, WAIT_OUTCOME_TTL_MS);
|
|
19519
19837
|
}
|
|
19520
19838
|
function anchorCwd(harness, session, cwd) {
|
|
19521
19839
|
if (session.cwd !== void 0 || cwd.trim() === "")
|
|
@@ -19584,7 +19902,7 @@ function createNarrativeService(options = {}) {
|
|
|
19584
19902
|
function watchResolution(resolution) {
|
|
19585
19903
|
if (resolution.lookedUp.length === 0)
|
|
19586
19904
|
return;
|
|
19587
|
-
const planPath = resolution.planPath ??
|
|
19905
|
+
const planPath = resolution.planPath ?? join28(resolution.root, ".wingman", "plan.md");
|
|
19588
19906
|
const planPathIdentity = resolution.planPathIdentity;
|
|
19589
19907
|
if (projectWatchers.has(planPathIdentity))
|
|
19590
19908
|
return;
|
|
@@ -19669,13 +19987,60 @@ function createNarrativeService(options = {}) {
|
|
|
19669
19987
|
});
|
|
19670
19988
|
}
|
|
19671
19989
|
}
|
|
19990
|
+
async function discoverStartupSessions() {
|
|
19991
|
+
const homeDir = options.homeDir;
|
|
19992
|
+
if (closed || homeDir === void 0)
|
|
19993
|
+
return;
|
|
19994
|
+
const scanAt = now().getTime();
|
|
19995
|
+
await Promise.all([
|
|
19996
|
+
["cc", discoverRecentSessions],
|
|
19997
|
+
["codex", discoverRecentSessions2]
|
|
19998
|
+
].map(async ([harness, discover]) => {
|
|
19999
|
+
const sessions = sessionsOf(harness);
|
|
20000
|
+
const limit = MAX_SESSIONS - sessions.size;
|
|
20001
|
+
if (limit <= 0)
|
|
20002
|
+
return;
|
|
20003
|
+
try {
|
|
20004
|
+
const recent = await discover(homeDir, {
|
|
20005
|
+
now: scanAt,
|
|
20006
|
+
windowMs: STARTUP_DISCOVERY_WINDOW_MS,
|
|
20007
|
+
limit
|
|
20008
|
+
});
|
|
20009
|
+
for (const record of recent) {
|
|
20010
|
+
if (closed || sessions.size >= MAX_SESSIONS)
|
|
20011
|
+
break;
|
|
20012
|
+
if (sessions.has(record.id))
|
|
20013
|
+
continue;
|
|
20014
|
+
const session = sessionOf(harness, record.id);
|
|
20015
|
+
if (record.cwd !== void 0) {
|
|
20016
|
+
anchorCwd(harness, session, record.cwd);
|
|
20017
|
+
const base = pathBasename(record.cwd);
|
|
20018
|
+
if (base !== "")
|
|
20019
|
+
session.label = base;
|
|
20020
|
+
}
|
|
20021
|
+
session.discoveredAt = startedAt;
|
|
20022
|
+
session.lastActivity = new Date(record.mtime).toISOString();
|
|
20023
|
+
resetTranscript(session, record.transcriptPath);
|
|
20024
|
+
if (follow) {
|
|
20025
|
+
startFollowing(harness, session, record.transcriptPath);
|
|
20026
|
+
if (harness === "cc")
|
|
20027
|
+
startSubagentDiscovery(harness, session, record.transcriptPath);
|
|
20028
|
+
}
|
|
20029
|
+
notify(harness);
|
|
20030
|
+
}
|
|
20031
|
+
} catch {
|
|
20032
|
+
process.stderr.write(`[wingman] ${harness} startup discovery failed; skipped this harness.
|
|
20033
|
+
`);
|
|
20034
|
+
}
|
|
20035
|
+
}));
|
|
20036
|
+
}
|
|
19672
20037
|
function projectChanged(planPathIdentity) {
|
|
19673
20038
|
for (const [harness, sessions] of harnesses) {
|
|
19674
20039
|
let changed = false;
|
|
19675
20040
|
for (const session of sessions.values()) {
|
|
19676
20041
|
const resolution = session.projectResolution;
|
|
19677
20042
|
if (resolution?.planPathIdentity === planPathIdentity) {
|
|
19678
|
-
const planPath = resolution.planPath ??
|
|
20043
|
+
const planPath = resolution.planPath ?? join28(resolution.root, ".wingman", "plan.md");
|
|
19679
20044
|
void applyPendingPlanWrites(session, planPath, planPathIdentity).then(() => {
|
|
19680
20045
|
session.dirty = true;
|
|
19681
20046
|
notify(harness);
|
|
@@ -19720,7 +20085,7 @@ function createNarrativeService(options = {}) {
|
|
|
19720
20085
|
}
|
|
19721
20086
|
const resolution = session.projectResolution;
|
|
19722
20087
|
if (resolution !== void 0) {
|
|
19723
|
-
const planPath = resolution.planPath ??
|
|
20088
|
+
const planPath = resolution.planPath ?? join28(resolution.root, ".wingman", "plan.md");
|
|
19724
20089
|
void applyPendingPlanWrites(session, planPath, resolution.planPathIdentity).then(() => {
|
|
19725
20090
|
session.dirty = true;
|
|
19726
20091
|
notify(harness);
|
|
@@ -19830,9 +20195,11 @@ function createNarrativeService(options = {}) {
|
|
|
19830
20195
|
if (closed || generation !== session.generation)
|
|
19831
20196
|
return;
|
|
19832
20197
|
let timestamp;
|
|
20198
|
+
let contentActivity = false;
|
|
19833
20199
|
if (harness === "codex") {
|
|
19834
20200
|
const parsed = parseCodexRolloutLine(line);
|
|
19835
20201
|
session.codexLines.push(parsed);
|
|
20202
|
+
contentActivity = parsed.kind === "user" || parsed.kind === "assistant" || parsed.kind === "tool_call" || parsed.kind === "tool_result";
|
|
19836
20203
|
if ((parsed.kind === "session_meta" && parsed.parentThreadId === void 0 || parsed.kind === "turn_context") && parsed.cwd !== void 0) {
|
|
19837
20204
|
anchorCwd(harness, session, parsed.cwd);
|
|
19838
20205
|
}
|
|
@@ -19841,11 +20208,30 @@ function createNarrativeService(options = {}) {
|
|
|
19841
20208
|
} else {
|
|
19842
20209
|
const parsed = parseTranscriptLine(line);
|
|
19843
20210
|
session.lines.push(parsed);
|
|
20211
|
+
contentActivity = parsed.kind === "user" || parsed.kind === "assistant";
|
|
19844
20212
|
if (parsed.kind !== "unknown")
|
|
19845
20213
|
timestamp = parsed.timestamp;
|
|
20214
|
+
const waiting = session.waiting;
|
|
20215
|
+
if (harness === "cc" && path === session.transcriptPath && waiting?.kind === "permission" && parsed.kind === "user" && parsed.timestamp !== void 0 && Date.parse(parsed.timestamp) >= Date.parse(waiting.since) - 5e3 && (parsed.raw.toolDenialKind === void 0 || parsed.raw.toolDenialKind === "user-rejected") && parsed.toolResults.some((result5) => result5.isError && (waiting.toolUseId === void 0 || result5.toolUseId === waiting.toolUseId) && (parsed.raw.toolDenialKind === "user-rejected" || parsed.toolUseResult === "User rejected tool use" || parsed.raw.toolDenialKind === void 0 && typeof result5.content === "string" && result5.content.startsWith("The user doesn't want to proceed with this tool use")))) {
|
|
20216
|
+
session.waitEpisodes.push({
|
|
20217
|
+
...waiting,
|
|
20218
|
+
get message() {
|
|
20219
|
+
return waiting.message;
|
|
20220
|
+
},
|
|
20221
|
+
until: parsed.timestamp,
|
|
20222
|
+
resolvedBy: "transcript:user-rejected"
|
|
20223
|
+
});
|
|
20224
|
+
session.waiting = null;
|
|
20225
|
+
session.waitingToolName = void 0;
|
|
20226
|
+
session.feedbackState = void 0;
|
|
20227
|
+
recordWaitOutcome(harness, session, waiting, "denied", "cc transcript tool_result(user-rejected)");
|
|
20228
|
+
}
|
|
20229
|
+
}
|
|
20230
|
+
if (session.discoveredAt !== void 0 && path === session.transcriptPath && timestamp !== void 0) {
|
|
20231
|
+
session.lastActivity = timestamp;
|
|
19846
20232
|
}
|
|
19847
20233
|
const endedAt = session.endedAt ?? session.stopAt;
|
|
19848
|
-
if (timestamp !== void 0 && endedAt !== void 0 && Date.parse(timestamp) > Date.parse(endedAt)) {
|
|
20234
|
+
if (contentActivity && timestamp !== void 0 && endedAt !== void 0 && Date.parse(timestamp) > Date.parse(endedAt)) {
|
|
19849
20235
|
session.endedAt = void 0;
|
|
19850
20236
|
session.stopAt = void 0;
|
|
19851
20237
|
}
|
|
@@ -19858,7 +20244,7 @@ function createNarrativeService(options = {}) {
|
|
|
19858
20244
|
const sessionDir = transcriptPath.replace(/\.jsonl$/, "");
|
|
19859
20245
|
if (sessionDir === transcriptPath)
|
|
19860
20246
|
return;
|
|
19861
|
-
const subagentsDir =
|
|
20247
|
+
const subagentsDir = join28(sessionDir, "subagents");
|
|
19862
20248
|
const generation = session.generation;
|
|
19863
20249
|
const poll = async () => {
|
|
19864
20250
|
try {
|
|
@@ -19868,7 +20254,7 @@ function createNarrativeService(options = {}) {
|
|
|
19868
20254
|
}
|
|
19869
20255
|
for (const entry of entries) {
|
|
19870
20256
|
if (/^agent-.*\.jsonl$/.test(entry)) {
|
|
19871
|
-
startFollowing(harness, session,
|
|
20257
|
+
startFollowing(harness, session, join28(subagentsDir, entry), generation);
|
|
19872
20258
|
}
|
|
19873
20259
|
}
|
|
19874
20260
|
} catch {
|
|
@@ -19886,6 +20272,7 @@ function createNarrativeService(options = {}) {
|
|
|
19886
20272
|
const sessionId = typeof payload.session_id === "string" ? payload.session_id : void 0;
|
|
19887
20273
|
const key = sessionId ?? transcriptPath ?? "__nosession__";
|
|
19888
20274
|
const session = sessionOf(event.harness, key);
|
|
20275
|
+
session.discoveredAt = void 0;
|
|
19889
20276
|
session.lastActivity = event.received_at;
|
|
19890
20277
|
const cwd = typeof payload.cwd === "string" ? payload.cwd : void 0;
|
|
19891
20278
|
if (cwd !== void 0) {
|
|
@@ -19935,7 +20322,9 @@ function createNarrativeService(options = {}) {
|
|
|
19935
20322
|
session.pendingHookTool = {
|
|
19936
20323
|
toolName: payload.tool_name,
|
|
19937
20324
|
detail: hookToolDetail(payload.tool_input),
|
|
19938
|
-
since: event.received_at
|
|
20325
|
+
since: event.received_at,
|
|
20326
|
+
...event.harness === "cc" && typeof payload.tool_use_id === "string" ? { toolUseId: payload.tool_use_id } : {},
|
|
20327
|
+
...event.harness === "cc" ? { toolInput: payload.tool_input } : {}
|
|
19939
20328
|
};
|
|
19940
20329
|
} else if (name === "PostToolUse" && typeof payload.tool_name === "string" || name === "Stop" || name === "SessionEnd") {
|
|
19941
20330
|
session.pendingHookTool = void 0;
|
|
@@ -19943,24 +20332,33 @@ function createNarrativeService(options = {}) {
|
|
|
19943
20332
|
const signal = waitingSignal(payload);
|
|
19944
20333
|
if (signal !== null) {
|
|
19945
20334
|
const { kind } = signal;
|
|
20335
|
+
const toolUseId = event.harness === "cc" && name === "PermissionRequest" && session.pendingHookTool !== void 0 && session.pendingHookTool.toolName === payload.tool_name && JSON.stringify(session.pendingHookTool.toolInput) === JSON.stringify(payload.tool_input) ? session.pendingHookTool.toolUseId : void 0;
|
|
19946
20336
|
session.feedbackRequestAt = event.received_at;
|
|
19947
20337
|
if (session.waiting === null) {
|
|
20338
|
+
clearWaitOutcome(session);
|
|
20339
|
+
session.waitingToolName = event.harness === "cc" && typeof payload.tool_name === "string" ? payload.tool_name : void 0;
|
|
19948
20340
|
session.waiting = {
|
|
19949
20341
|
kind,
|
|
19950
20342
|
get message() {
|
|
19951
20343
|
return signal.message;
|
|
19952
20344
|
},
|
|
19953
20345
|
...signal.messageI18n === void 0 ? {} : { messageI18n: signal.messageI18n },
|
|
19954
|
-
since: event.received_at
|
|
20346
|
+
since: event.received_at,
|
|
20347
|
+
...toolUseId === void 0 ? {} : { toolUseId }
|
|
19955
20348
|
};
|
|
19956
20349
|
} else if (kind === "permission" || session.waiting.kind === kind) {
|
|
20350
|
+
const retainedToolUseId = toolUseId ?? session.waiting.toolUseId;
|
|
20351
|
+
if (event.harness === "cc" && typeof payload.tool_name === "string") {
|
|
20352
|
+
session.waitingToolName = payload.tool_name;
|
|
20353
|
+
}
|
|
19957
20354
|
session.waiting = {
|
|
19958
20355
|
kind,
|
|
19959
20356
|
get message() {
|
|
19960
20357
|
return signal.message;
|
|
19961
20358
|
},
|
|
19962
20359
|
...signal.messageI18n === void 0 ? {} : { messageI18n: signal.messageI18n },
|
|
19963
|
-
since: session.waiting.since
|
|
20360
|
+
since: session.waiting.since,
|
|
20361
|
+
...retainedToolUseId === void 0 ? {} : { toolUseId: retainedToolUseId }
|
|
19964
20362
|
};
|
|
19965
20363
|
}
|
|
19966
20364
|
session.feedbackState = {
|
|
@@ -19971,7 +20369,8 @@ function createNarrativeService(options = {}) {
|
|
|
19971
20369
|
return signal.message;
|
|
19972
20370
|
}
|
|
19973
20371
|
};
|
|
19974
|
-
} else {
|
|
20372
|
+
} else if (!(event.harness === "cc" && session.waiting?.toolUseId !== void 0 && (name === "PreToolUse" || name === "PostToolUse") && payload.tool_use_id !== session.waiting.toolUseId)) {
|
|
20373
|
+
const allowed = event.harness === "cc" && session.waiting?.kind === "permission" && name === "PostToolUse" && (session.waiting.toolUseId !== void 0 ? payload.tool_use_id === session.waiting.toolUseId : session.waitingToolName !== void 0 && payload.tool_name === session.waitingToolName);
|
|
19975
20374
|
if (session.waiting !== null) {
|
|
19976
20375
|
const waiting = session.waiting;
|
|
19977
20376
|
session.waitEpisodes.push({
|
|
@@ -19984,9 +20383,13 @@ function createNarrativeService(options = {}) {
|
|
|
19984
20383
|
...session.feedbackRequestAt === void 0 ? {} : { requestAt: session.feedbackRequestAt }
|
|
19985
20384
|
});
|
|
19986
20385
|
session.waiting = null;
|
|
20386
|
+
session.waitingToolName = void 0;
|
|
20387
|
+
if (allowed) {
|
|
20388
|
+
recordWaitOutcome(event.harness, session, waiting, "allowed", `cc PostToolUse tool_use_id=${typeof payload.tool_use_id === "string" ? payload.tool_use_id : "none"}`);
|
|
20389
|
+
}
|
|
19987
20390
|
}
|
|
19988
20391
|
const resetFeedback = name === "UserPromptSubmit" || name === "Stop" || name === "SessionEnd";
|
|
19989
|
-
if (resetFeedback) {
|
|
20392
|
+
if (allowed || resetFeedback) {
|
|
19990
20393
|
session.feedbackState = void 0;
|
|
19991
20394
|
} else if (session.feedbackState?.state === "needs_user") {
|
|
19992
20395
|
const previous = session.feedbackState;
|
|
@@ -20102,15 +20505,29 @@ function createNarrativeService(options = {}) {
|
|
|
20102
20505
|
const infos = [...sessions.values()].map((session) => {
|
|
20103
20506
|
const user = overlayEntries[`${harness}:${session.id}`];
|
|
20104
20507
|
const lastActivity = lastActivityOf(session);
|
|
20508
|
+
const lastInstruction = session.hookInstructions.at(-1)?.at;
|
|
20105
20509
|
const state = deriveCached(harness, session, configuredPlugins, configuredMcpServers);
|
|
20510
|
+
const ended = isEnded(session, nowIso);
|
|
20511
|
+
const turnEnded = session.stopAt !== void 0 && !ended && state.waiting === null && feedbackView(harness, feedback, humanFeedbackState(harness, session)).state !== "needs_user";
|
|
20106
20512
|
return {
|
|
20107
20513
|
id: session.id,
|
|
20514
|
+
...session.discoveredAt === void 0 ? {} : { discovered: true },
|
|
20108
20515
|
...state.origin === void 0 ? {} : { origin: state.origin },
|
|
20109
20516
|
label: session.projectResolution?.isHome ? t("narrative.homeDirectory") : session.label ?? shortSessionId(session.id),
|
|
20110
20517
|
...session.cwd === void 0 ? {} : { cwd: session.cwd },
|
|
20111
20518
|
lastActivity,
|
|
20519
|
+
...lastInstruction === void 0 ? {} : { lastInstruction },
|
|
20112
20520
|
waiting: state.waiting !== null,
|
|
20113
|
-
ended
|
|
20521
|
+
ended,
|
|
20522
|
+
...turnEnded ? { turnEnded: true } : {},
|
|
20523
|
+
...state.waiting === null && session.waitOutcome !== void 0 && Date.parse(nowIso) - Date.parse(session.waitOutcome.at) < WAIT_OUTCOME_TTL_MS ? {
|
|
20524
|
+
waitOutcome: {
|
|
20525
|
+
outcome: session.waitOutcome.outcome,
|
|
20526
|
+
at: session.waitOutcome.at,
|
|
20527
|
+
message: session.waitOutcome.message,
|
|
20528
|
+
source: session.waitOutcome.source
|
|
20529
|
+
}
|
|
20530
|
+
} : {},
|
|
20114
20531
|
archived: user?.archived === true,
|
|
20115
20532
|
archivedHasNewActivity: user?.archived === true && user.archivedAt !== void 0 && Date.parse(lastActivity) > Date.parse(user.archivedAt),
|
|
20116
20533
|
...feedback === void 0 ? {} : { feedback }
|
|
@@ -20302,7 +20719,7 @@ function createNarrativeService(options = {}) {
|
|
|
20302
20719
|
continue;
|
|
20303
20720
|
const resolution = group.resolution;
|
|
20304
20721
|
const root = resolution?.root ?? (group.cardId === void 0 ? resolve12(members[0]?.session.cwd ?? rootIdentity) : rootIdentity);
|
|
20305
|
-
const planPath = resolution?.planPath ??
|
|
20722
|
+
const planPath = resolution?.planPath ?? join28(root, ".wingman", "plan.md");
|
|
20306
20723
|
const runtime = projectFiles.get(resolution?.planPathIdentity ?? planPath);
|
|
20307
20724
|
if (runtime?.current !== void 0 && runtime.readFailureKey === void 0 && runtime.parsedLocale !== getLocale()) {
|
|
20308
20725
|
runtime.parsed = parseProjectPlan(runtime.current.content, {
|
|
@@ -20331,8 +20748,11 @@ function createNarrativeService(options = {}) {
|
|
|
20331
20748
|
return {
|
|
20332
20749
|
harness,
|
|
20333
20750
|
id: session.id,
|
|
20751
|
+
...info?.discovered === void 0 ? {} : { discovered: true },
|
|
20334
20752
|
label,
|
|
20335
20753
|
ended: info?.ended ?? false,
|
|
20754
|
+
...info?.turnEnded === true ? { turnEnded: true } : {},
|
|
20755
|
+
...info?.waitOutcome === void 0 ? {} : { waitOutcome: info.waitOutcome },
|
|
20336
20756
|
...state?.origin === void 0 ? {} : { origin: state.origin },
|
|
20337
20757
|
...state?.skillsUsed === void 0 ? {} : { skillsUsed: state.skillsUsed },
|
|
20338
20758
|
title: attachedTitle !== void 0 ? { text: attachedTitle, source: "plan.md \u6B65\u9AA4" } : planInstruction !== void 0 ? { text: truncate(planInstruction, DETAIL_LIMIT), source: "\u8BA1\u5212\u6240\u5C5E\u6307\u4EE4" } : instructionTitle !== void 0 ? { text: truncate(instructionTitle, DETAIL_LIMIT), source: "\u6700\u65B0\u6307\u4EE4" } : { text: label, source: "\u5DE5\u4F5C\u76EE\u5F55" },
|
|
@@ -20517,6 +20937,8 @@ function createNarrativeService(options = {}) {
|
|
|
20517
20937
|
}
|
|
20518
20938
|
function close() {
|
|
20519
20939
|
closed = true;
|
|
20940
|
+
if (startupDiscovery !== void 0)
|
|
20941
|
+
clearImmediate(startupDiscovery);
|
|
20520
20942
|
for (const sessions of harnesses.values()) {
|
|
20521
20943
|
for (const session of sessions.values())
|
|
20522
20944
|
closeSession(session);
|
|
@@ -20543,6 +20965,7 @@ function createNarrativeService(options = {}) {
|
|
|
20543
20965
|
notify(changed);
|
|
20544
20966
|
}
|
|
20545
20967
|
loadRememberedProjectRoots();
|
|
20968
|
+
const startupDiscovery = options.discoverOnStart === false ? void 0 : setImmediate(() => void discoverStartupSessions());
|
|
20546
20969
|
return {
|
|
20547
20970
|
setCodexPluginsProvider(provider) {
|
|
20548
20971
|
codexPluginsProvider = provider;
|
|
@@ -21673,7 +22096,7 @@ init_dist6();
|
|
|
21673
22096
|
init_dist3();
|
|
21674
22097
|
init_dist();
|
|
21675
22098
|
import { homedir as homedir14 } from "node:os";
|
|
21676
|
-
import { createInterface } from "node:readline/promises";
|
|
22099
|
+
import { createInterface as createInterface3 } from "node:readline/promises";
|
|
21677
22100
|
var ProtocolUsageError = class extends Error {
|
|
21678
22101
|
};
|
|
21679
22102
|
async function runProtocolCli(args, options = { homeDir: homedir14() }) {
|
|
@@ -21830,7 +22253,7 @@ function lines(text) {
|
|
|
21830
22253
|
return values;
|
|
21831
22254
|
}
|
|
21832
22255
|
async function confirmWrite() {
|
|
21833
|
-
const prompt =
|
|
22256
|
+
const prompt = createInterface3({ input: process.stdin, output: process.stdout });
|
|
21834
22257
|
try {
|
|
21835
22258
|
const answer = await prompt.question(t("cli.confirmWrite"));
|
|
21836
22259
|
return answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes";
|
|
@@ -21891,10 +22314,18 @@ async function loadHarness(harness, mode) {
|
|
|
21891
22314
|
}
|
|
21892
22315
|
|
|
21893
22316
|
// apps/cli/dist/return-target.js
|
|
22317
|
+
init_dist2();
|
|
21894
22318
|
init_dist();
|
|
21895
22319
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
21896
|
-
import { closeSync as closeSync3, copyFileSync as copyFileSync3, mkdirSync as mkdirSync12, openSync as openSync3, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync10, statSync as
|
|
21897
|
-
import { dirname as dirname18, join as
|
|
22320
|
+
import { closeSync as closeSync3, copyFileSync as copyFileSync3, mkdirSync as mkdirSync12, openSync as openSync3, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync10, statSync as statSync9, writeFileSync as writeFileSync13 } from "node:fs";
|
|
22321
|
+
import { dirname as dirname18, join as join29, resolve as resolve13 } from "node:path";
|
|
22322
|
+
var FREE_HARNESS_SWITCH_COOLDOWN_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
22323
|
+
function isHarnessId3(value) {
|
|
22324
|
+
return typeof value === "string" && HARNESS_IDS.includes(value);
|
|
22325
|
+
}
|
|
22326
|
+
function isIsoTimestamp(value) {
|
|
22327
|
+
return typeof value === "string" && Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
|
|
22328
|
+
}
|
|
21898
22329
|
function isIslandSetting(value) {
|
|
21899
22330
|
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");
|
|
21900
22331
|
}
|
|
@@ -21908,13 +22339,13 @@ var BUNDLES = [
|
|
|
21908
22339
|
["kitty", "kitty.app"],
|
|
21909
22340
|
["VS Code", "Visual Studio Code.app"]
|
|
21910
22341
|
];
|
|
21911
|
-
function detectReturnTargets(homeDir, roots = ["/Applications",
|
|
22342
|
+
function detectReturnTargets(homeDir, roots = ["/Applications", join29(homeDir, "Applications")]) {
|
|
21912
22343
|
const available = [];
|
|
21913
22344
|
for (const [name, bundle] of BUNDLES) {
|
|
21914
22345
|
for (const root of new Set(roots.map((root2) => resolve13(root2)))) {
|
|
21915
|
-
const bundlePath =
|
|
22346
|
+
const bundlePath = join29(root, bundle);
|
|
21916
22347
|
try {
|
|
21917
|
-
if (
|
|
22348
|
+
if (statSync9(bundlePath).isDirectory())
|
|
21918
22349
|
available.push({ name, bundlePath });
|
|
21919
22350
|
} catch {
|
|
21920
22351
|
}
|
|
@@ -21923,7 +22354,7 @@ function detectReturnTargets(homeDir, roots = ["/Applications", join27(homeDir,
|
|
|
21923
22354
|
return available;
|
|
21924
22355
|
}
|
|
21925
22356
|
function settingsPath(homeDir) {
|
|
21926
|
-
return
|
|
22357
|
+
return join29(homeDir, ".wingman", "state", "settings.json");
|
|
21927
22358
|
}
|
|
21928
22359
|
function readReturnTargetSettings(homeDir) {
|
|
21929
22360
|
let raw;
|
|
@@ -21953,12 +22384,18 @@ function saveSettings(homeDir, patch) {
|
|
|
21953
22384
|
if (patch.island !== void 0 && !isIslandSetting(patch.island)) {
|
|
21954
22385
|
return { unavailable: t("cli.server.settingsInvalid") };
|
|
21955
22386
|
}
|
|
22387
|
+
if (patch.freeHarness !== void 0 && !isHarnessId3(patch.freeHarness)) {
|
|
22388
|
+
return { unavailable: t("cli.server.settingsInvalid") };
|
|
22389
|
+
}
|
|
22390
|
+
if (patch.freeHarnessChosenAt !== void 0 && !isIsoTimestamp(patch.freeHarnessChosenAt)) {
|
|
22391
|
+
return { unavailable: t("cli.server.settingsInvalid") };
|
|
22392
|
+
}
|
|
21956
22393
|
const current = readReturnTargetSettings(homeDir);
|
|
21957
22394
|
if ("unavailable" in current)
|
|
21958
22395
|
return current;
|
|
21959
22396
|
const settings = { ...current, ...patch };
|
|
21960
22397
|
const path = settingsPath(homeDir);
|
|
21961
|
-
const tempPath =
|
|
22398
|
+
const tempPath = join29(dirname18(path), `.settings-${randomBytes4(8).toString("hex")}.tmp`);
|
|
21962
22399
|
let fd;
|
|
21963
22400
|
try {
|
|
21964
22401
|
mkdirSync12(dirname18(path), { recursive: true, mode: 448 });
|
|
@@ -21991,10 +22428,17 @@ function saveSettings(homeDir, patch) {
|
|
|
21991
22428
|
}
|
|
21992
22429
|
}
|
|
21993
22430
|
function isSettings(value) {
|
|
21994
|
-
if (!isRecord8(value) || value.version !== 1 || !Object.keys(value).every((key) => [
|
|
22431
|
+
if (!isRecord8(value) || value.version !== 1 || !Object.keys(value).every((key) => [
|
|
22432
|
+
"version",
|
|
22433
|
+
"returnTarget",
|
|
22434
|
+
"locale",
|
|
22435
|
+
"island",
|
|
22436
|
+
"freeHarness",
|
|
22437
|
+
"freeHarnessChosenAt"
|
|
22438
|
+
].includes(key))) {
|
|
21995
22439
|
return false;
|
|
21996
22440
|
}
|
|
21997
|
-
return (value.island === void 0 || isIslandSetting(value.island)) && (value.returnTarget === void 0 || isRecord8(value.returnTarget) && Object.keys(value.returnTarget).every((key) => key === "bundlePath") && typeof value.returnTarget.bundlePath === "string" && value.returnTarget.bundlePath.startsWith("/"));
|
|
22441
|
+
return (value.island === void 0 || isIslandSetting(value.island)) && (value.freeHarness === void 0 || isHarnessId3(value.freeHarness)) && (value.freeHarnessChosenAt === void 0 || isIsoTimestamp(value.freeHarnessChosenAt)) && (value.returnTarget === void 0 || isRecord8(value.returnTarget) && Object.keys(value.returnTarget).every((key) => key === "bundlePath") && typeof value.returnTarget.bundlePath === "string" && value.returnTarget.bundlePath.startsWith("/"));
|
|
21998
22442
|
}
|
|
21999
22443
|
function isRecord8(value) {
|
|
22000
22444
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -22004,7 +22448,7 @@ function isRecord8(value) {
|
|
|
22004
22448
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
22005
22449
|
import { closeSync as closeSync4, mkdirSync as mkdirSync13, openSync as openSync4, readFileSync as readFileSync19, renameSync as renameSync6, rmSync as rmSync11, writeFileSync as writeFileSync14 } from "node:fs";
|
|
22006
22450
|
import { homedir as homedir16 } from "node:os";
|
|
22007
|
-
import { dirname as dirname19, join as
|
|
22451
|
+
import { dirname as dirname19, join as join30 } from "node:path";
|
|
22008
22452
|
function createHookToken() {
|
|
22009
22453
|
return randomBytes5(32).toString("base64url");
|
|
22010
22454
|
}
|
|
@@ -22015,8 +22459,8 @@ function writeServeRuntimeState(port, token, options = {}) {
|
|
|
22015
22459
|
const pid = options.pid ?? process.pid;
|
|
22016
22460
|
const suffix = randomBytes5(8).toString("base64url");
|
|
22017
22461
|
const owner = `serve-${startedAtMs}-${pid}-${suffix}`;
|
|
22018
|
-
const path =
|
|
22019
|
-
const tempPath =
|
|
22462
|
+
const path = join30(options.homeDir ?? homedir16(), ".wingman", "state", "serve", `${owner}.json`);
|
|
22463
|
+
const tempPath = join30(dirname19(path), `.${owner}.tmp`);
|
|
22020
22464
|
const contents = Buffer.from(`${JSON.stringify({ version: 2, owner, pid, port, startedAtMs, token })}
|
|
22021
22465
|
`, "utf8");
|
|
22022
22466
|
let fd;
|
|
@@ -22420,7 +22864,20 @@ async function handle(req, res, options, warn, runtime) {
|
|
|
22420
22864
|
return;
|
|
22421
22865
|
}
|
|
22422
22866
|
if (url.pathname === "/api/license") {
|
|
22423
|
-
|
|
22867
|
+
const body = publicLicenseStatus(licenseStatus(options.licenseOptions));
|
|
22868
|
+
body.tier = checkLicense(options.licenseOptions) ? "full" : "free";
|
|
22869
|
+
if (body.tier === "free") {
|
|
22870
|
+
const cached = runtime.anatomy?.configs;
|
|
22871
|
+
const detected = new Set((cached ?? []).map((config) => config.harness));
|
|
22872
|
+
const homeDir = options.homeDir ?? options.licenseOptions?.homeDir;
|
|
22873
|
+
const settings = homeDir === void 0 ? void 0 : readReturnTargetSettings(homeDir);
|
|
22874
|
+
const selected = settings && !("unavailable" in settings) ? settings.freeHarness : void 0;
|
|
22875
|
+
body.freeHarness = selected !== void 0 && (cached === void 0 || detected.has(selected)) ? selected : HARNESS_IDS.find((harness) => detected.has(harness)) ?? HARNESS_IDS[0];
|
|
22876
|
+
if (settings && !("unavailable" in settings) && settings.freeHarnessChosenAt !== void 0) {
|
|
22877
|
+
body.freeHarnessSwitchableAt = new Date(Date.parse(settings.freeHarnessChosenAt) + FREE_HARNESS_SWITCH_COOLDOWN_MS).toISOString();
|
|
22878
|
+
}
|
|
22879
|
+
}
|
|
22880
|
+
sendJson2(res, 200, body);
|
|
22424
22881
|
return;
|
|
22425
22882
|
}
|
|
22426
22883
|
if (url.pathname === "/api/projects") {
|
|
@@ -22627,10 +23084,6 @@ async function handleActionApply(req, res, options, runtime) {
|
|
|
22627
23084
|
sendJson2(res, 403, { error: t("cli.server.fixturesAction") });
|
|
22628
23085
|
return;
|
|
22629
23086
|
}
|
|
22630
|
-
if (!checkLicense(options.licenseOptions)) {
|
|
22631
|
-
sendJson2(res, 403, { error: t("cli.server.subscriptionRequired") });
|
|
22632
|
-
return;
|
|
22633
|
-
}
|
|
22634
23087
|
const body = await readJsonBody(req);
|
|
22635
23088
|
if (body === void 0) {
|
|
22636
23089
|
sendJson2(res, 400, { error: t("cli.server.jsonBody") });
|
|
@@ -22640,6 +23093,10 @@ async function handleActionApply(req, res, options, runtime) {
|
|
|
22640
23093
|
handleProtocolUserAction(body, res, options, runtime);
|
|
22641
23094
|
return;
|
|
22642
23095
|
}
|
|
23096
|
+
if (!checkLicense(options.licenseOptions)) {
|
|
23097
|
+
sendJson2(res, 403, { error: t("cli.server.subscriptionRequired") });
|
|
23098
|
+
return;
|
|
23099
|
+
}
|
|
22643
23100
|
const { harness, plan } = body;
|
|
22644
23101
|
const loaded = pickHarness(options, harness);
|
|
22645
23102
|
if (!loaded) {
|
|
@@ -22733,18 +23190,50 @@ async function handleSettings(req, res, options, runtime) {
|
|
|
22733
23190
|
}
|
|
22734
23191
|
if (req.method === "POST") {
|
|
22735
23192
|
const body = await readJsonBody(req);
|
|
22736
|
-
if (!isRecord9(body) || Object.keys(body).length === 0 || Object.keys(body).some((key) =>
|
|
23193
|
+
if (!isRecord9(body) || Object.keys(body).length === 0 || Object.keys(body).some((key) => !["locale", "island", "freeHarness"].includes(key)) || body.locale !== void 0 && !locales().some(({ tag }) => tag === body.locale) || body.island !== void 0 && !isIslandSetting(body.island) || body.freeHarness !== void 0 && !isHarnessId4(body.freeHarness)) {
|
|
22737
23194
|
sendJson2(res, 400, { error: t("cli.server.settingsInvalid") });
|
|
22738
23195
|
return;
|
|
22739
23196
|
}
|
|
22740
|
-
|
|
22741
|
-
|
|
22742
|
-
...isIslandSetting(body.island) ? { island: body.island } : {}
|
|
22743
|
-
});
|
|
22744
|
-
if ("unavailable" in result5) {
|
|
22745
|
-
sendJson2(res, 409, { error: result5.unavailable });
|
|
23197
|
+
if (isHarnessId4(body.freeHarness) && runtime.anatomy !== null && !runtime.anatomy.configs.some((config) => config.harness === body.freeHarness)) {
|
|
23198
|
+
sendJson2(res, 400, { error: t("cli.server.freeHarnessNotDetected") });
|
|
22746
23199
|
return;
|
|
22747
23200
|
}
|
|
23201
|
+
let freeHarnessChosenAt;
|
|
23202
|
+
if (isHarnessId4(body.freeHarness)) {
|
|
23203
|
+
const settings2 = readReturnTargetSettings(options.homeDir);
|
|
23204
|
+
if ("unavailable" in settings2) {
|
|
23205
|
+
sendJson2(res, 409, { error: settings2.unavailable });
|
|
23206
|
+
return;
|
|
23207
|
+
}
|
|
23208
|
+
const now = options.now?.() ?? options.licenseOptions?.now ?? /* @__PURE__ */ new Date();
|
|
23209
|
+
const freeHarnessUnchanged = settings2.freeHarness === body.freeHarness && settings2.freeHarnessChosenAt !== void 0;
|
|
23210
|
+
if (settings2.freeHarnessChosenAt !== void 0 && !freeHarnessUnchanged) {
|
|
23211
|
+
const switchableAt = new Date(Date.parse(settings2.freeHarnessChosenAt) + FREE_HARNESS_SWITCH_COOLDOWN_MS);
|
|
23212
|
+
if (now.getTime() < switchableAt.getTime()) {
|
|
23213
|
+
sendJson2(res, 409, {
|
|
23214
|
+
error: t("cli.server.freeHarnessCooldown", {
|
|
23215
|
+
switchableAt: `${switchableAt.getFullYear()}-${String(switchableAt.getMonth() + 1).padStart(2, "0")}-${String(switchableAt.getDate()).padStart(2, "0")}`
|
|
23216
|
+
}),
|
|
23217
|
+
switchableAt: switchableAt.toISOString()
|
|
23218
|
+
});
|
|
23219
|
+
return;
|
|
23220
|
+
}
|
|
23221
|
+
}
|
|
23222
|
+
if (!freeHarnessUnchanged)
|
|
23223
|
+
freeHarnessChosenAt = now.toISOString();
|
|
23224
|
+
}
|
|
23225
|
+
const patch = {
|
|
23226
|
+
...body.locale === void 0 ? {} : { locale: body.locale },
|
|
23227
|
+
...isIslandSetting(body.island) ? { island: body.island } : {},
|
|
23228
|
+
...isHarnessId4(body.freeHarness) && freeHarnessChosenAt !== void 0 ? { freeHarness: body.freeHarness, freeHarnessChosenAt } : {}
|
|
23229
|
+
};
|
|
23230
|
+
if (Object.keys(patch).length > 0) {
|
|
23231
|
+
const result5 = saveSettings(options.homeDir, patch);
|
|
23232
|
+
if ("unavailable" in result5) {
|
|
23233
|
+
sendJson2(res, 409, { error: result5.unavailable });
|
|
23234
|
+
return;
|
|
23235
|
+
}
|
|
23236
|
+
}
|
|
22748
23237
|
if (body.locale !== void 0) {
|
|
22749
23238
|
setLocale(body.locale);
|
|
22750
23239
|
options.narrative?.refreshLocale();
|
|
@@ -22760,7 +23249,8 @@ async function handleSettings(req, res, options, runtime) {
|
|
|
22760
23249
|
sendJson2(res, 200, {
|
|
22761
23250
|
...resolved,
|
|
22762
23251
|
available: locales(),
|
|
22763
|
-
..."unavailable" in settings || settings.island === void 0 ? {} : { island: settings.island }
|
|
23252
|
+
..."unavailable" in settings || settings.island === void 0 ? {} : { island: settings.island },
|
|
23253
|
+
..."unavailable" in settings || settings.freeHarness === void 0 ? {} : { freeHarness: settings.freeHarness }
|
|
22764
23254
|
});
|
|
22765
23255
|
}
|
|
22766
23256
|
async function handleReturn(req, res, options, activate) {
|
|
@@ -22861,7 +23351,7 @@ async function handleLicenseInstall(req, res, options) {
|
|
|
22861
23351
|
sendJson2(res, 400, { error: result5.error });
|
|
22862
23352
|
return;
|
|
22863
23353
|
}
|
|
22864
|
-
sendJson2(res, 200, publicLicenseStatus(result5.status));
|
|
23354
|
+
sendJson2(res, 200, { ...publicLicenseStatus(result5.status), tier: "full" });
|
|
22865
23355
|
}
|
|
22866
23356
|
async function handleLicenseRefresh(res, options) {
|
|
22867
23357
|
const homeDir = options.licenseRefreshOptions?.homeDir ?? options.licenseOptions?.homeDir;
|
|
@@ -22889,6 +23379,7 @@ async function handleLicenseRefresh(res, options) {
|
|
|
22889
23379
|
};
|
|
22890
23380
|
sendJson2(res, 200, {
|
|
22891
23381
|
...publicLicenseStatus(licenseStatus(statusOptions)),
|
|
23382
|
+
tier: "full",
|
|
22892
23383
|
message: result5.message
|
|
22893
23384
|
});
|
|
22894
23385
|
}
|
|
@@ -22930,7 +23421,7 @@ function isToggleRequest(value) {
|
|
|
22930
23421
|
return o.kind === "toggle" && typeof o.itemId === "string" && typeof o.enable === "boolean";
|
|
22931
23422
|
}
|
|
22932
23423
|
function isTaskOverlayRequest(value) {
|
|
22933
|
-
if (!isRecord9(value) || !
|
|
23424
|
+
if (!isRecord9(value) || !isHarnessId4(value.harness))
|
|
22934
23425
|
return false;
|
|
22935
23426
|
if ("root" in value)
|
|
22936
23427
|
return false;
|
|
@@ -22954,7 +23445,7 @@ function isProjectOverlayRequest(value) {
|
|
|
22954
23445
|
const keys = Object.keys(value.patch);
|
|
22955
23446
|
return keys.length > 0 && keys.every((key) => ["pinned", "order", "hidden", "archived"].includes(key)) && (value.patch.pinned === void 0 || typeof value.patch.pinned === "boolean") && (value.patch.hidden === void 0 || typeof value.patch.hidden === "boolean") && (value.patch.archived === void 0 || typeof value.patch.archived === "boolean") && (value.patch.order === void 0 || typeof value.patch.order === "number" && Number.isSafeInteger(value.patch.order) && value.patch.order >= 0);
|
|
22956
23447
|
}
|
|
22957
|
-
function
|
|
23448
|
+
function isHarnessId4(value) {
|
|
22958
23449
|
return typeof value === "string" && HARNESS_IDS.includes(value);
|
|
22959
23450
|
}
|
|
22960
23451
|
function isRecord9(value) {
|
|
@@ -23152,6 +23643,7 @@ async function runServe(args) {
|
|
|
23152
23643
|
}
|
|
23153
23644
|
const panelDistDir = panelDist === void 0 ? resolve15(dirname20(fileURLToPath2(import.meta.url)), "../../panel/dist") : resolve15(panelDist);
|
|
23154
23645
|
const narrative = createNarrativeService({
|
|
23646
|
+
discoverOnStart: !fixtures,
|
|
23155
23647
|
followTranscripts: !fixtures,
|
|
23156
23648
|
homeDir,
|
|
23157
23649
|
...fixtures ? { projectBoundaryDir: fixturesRoot } : {},
|
|
@@ -23206,7 +23698,7 @@ async function runHook(args) {
|
|
|
23206
23698
|
if (action !== "install" && action !== "uninstall" || harness === void 0) {
|
|
23207
23699
|
throw new UsageError(t("cli.hookUsage"));
|
|
23208
23700
|
}
|
|
23209
|
-
if (!
|
|
23701
|
+
if (!isHarnessId5(harness)) {
|
|
23210
23702
|
throw new UsageError(t("cli.hookHarness", { ids: HARNESS_IDS.join("|"), harness }));
|
|
23211
23703
|
}
|
|
23212
23704
|
let port = 7333;
|
|
@@ -23316,7 +23808,7 @@ function parseScanArgs(args) {
|
|
|
23316
23808
|
json = true;
|
|
23317
23809
|
} else if (arg === "--harness") {
|
|
23318
23810
|
const value = rest.shift();
|
|
23319
|
-
if (value === void 0 || !
|
|
23811
|
+
if (value === void 0 || !isHarnessId5(value)) {
|
|
23320
23812
|
throw new UsageError(t("cli.scanHarness", {
|
|
23321
23813
|
ids: HARNESS_IDS.join("|"),
|
|
23322
23814
|
value: value ?? t("cli.missingArgument")
|
|
@@ -23363,7 +23855,7 @@ function parseServeArgs(args) {
|
|
|
23363
23855
|
}
|
|
23364
23856
|
return { port, fixtures, panelDist, locale };
|
|
23365
23857
|
}
|
|
23366
|
-
function
|
|
23858
|
+
function isHarnessId5(value) {
|
|
23367
23859
|
return HARNESS_IDS.includes(value);
|
|
23368
23860
|
}
|
|
23369
23861
|
main(process.argv.slice(2)).then((code) => {
|