@grifhinz/logics-manager 2.2.0 → 2.3.1

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.
Files changed (43) hide show
  1. package/README.md +95 -1
  2. package/VERSION +1 -1
  3. package/clients/README.md +9 -0
  4. package/clients/shared-web/media/css/board.css +658 -0
  5. package/clients/shared-web/media/css/details.css +457 -0
  6. package/clients/shared-web/media/css/layout.css +123 -0
  7. package/clients/shared-web/media/css/toolbar.css +576 -0
  8. package/clients/shared-web/media/harnessApi.js +324 -0
  9. package/clients/shared-web/media/hostApi.js +213 -0
  10. package/clients/shared-web/media/hostApiContract.js +55 -0
  11. package/clients/shared-web/media/icon.png +0 -0
  12. package/clients/shared-web/media/layoutController.js +246 -0
  13. package/clients/shared-web/media/logics.svg +7 -0
  14. package/clients/shared-web/media/logicsModel.js +910 -0
  15. package/clients/shared-web/media/main.css +112 -0
  16. package/clients/shared-web/media/main.js +3 -0
  17. package/clients/shared-web/media/mainApp.js +1005 -0
  18. package/clients/shared-web/media/mainCore.js +604 -0
  19. package/clients/shared-web/media/mainInteractionHandlers.js +324 -0
  20. package/clients/shared-web/media/mainInteractions.js +378 -0
  21. package/clients/shared-web/media/renderBoard.js +3 -0
  22. package/clients/shared-web/media/renderBoardApp.js +1339 -0
  23. package/clients/shared-web/media/renderDetails.js +685 -0
  24. package/clients/shared-web/media/renderMarkdown.js +449 -0
  25. package/clients/shared-web/media/toolsPanelLayout.js +172 -0
  26. package/clients/shared-web/media/uiStatus.js +54 -0
  27. package/clients/shared-web/media/webviewChrome.js +405 -0
  28. package/clients/shared-web/media/webviewPersistence.js +116 -0
  29. package/clients/shared-web/media/webviewSelectors.js +491 -0
  30. package/clients/viewer/README.md +5 -0
  31. package/clients/viewer/browser-host.js +847 -0
  32. package/clients/viewer/index.html +237 -0
  33. package/clients/viewer/viewer.css +433 -0
  34. package/logics_manager/assist.py +9 -142
  35. package/logics_manager/assist_handoff.py +132 -0
  36. package/logics_manager/assist_surface.py +38 -0
  37. package/logics_manager/cli.py +78 -5
  38. package/logics_manager/flow.py +126 -24
  39. package/logics_manager/flow_evidence.py +63 -0
  40. package/logics_manager/update_check.py +138 -0
  41. package/logics_manager/viewer.py +533 -0
  42. package/package.json +12 -6
  43. package/pyproject.toml +1 -1
@@ -0,0 +1,1005 @@
1
+ (() => {
2
+ const vscode =
3
+ typeof acquireVsCodeApi === "function"
4
+ ? acquireVsCodeApi()
5
+ : {
6
+ postMessage: () => undefined,
7
+ getState: () => null,
8
+ setState: () => undefined
9
+ };
10
+ const board = document.getElementById("board");
11
+ const mainPane = document.getElementById("layout-main");
12
+ const layout = document.getElementById("layout");
13
+ const splitter = document.getElementById("splitter");
14
+ const details = document.getElementById("details");
15
+ const detailsBody = document.getElementById("details-body");
16
+ const detailsToggle = document.getElementById("details-toggle");
17
+ const detailsTitle = document.getElementById("details-title");
18
+ const detailsEyebrow = document.getElementById("details-eyebrow");
19
+ const filterToggle = document.getElementById("filter-toggle");
20
+ const filterPanel = document.getElementById("filter-panel");
21
+ const toolsToggle = document.getElementById("tools-toggle");
22
+ const toolsPanel = document.getElementById("tools-panel");
23
+ const searchInput = document.getElementById("search-input");
24
+ const groupBySelect = document.getElementById("group-by");
25
+ const sortBySelect = document.getElementById("sort-by");
26
+ const headerLogicsInsightsButton = document.getElementById("header-logics-insights");
27
+ const activityToggle = document.getElementById("activity-toggle");
28
+ const attentionToggle = document.getElementById("attention-toggle");
29
+ const activityPanel = document.getElementById("activity-panel");
30
+ const helpBanner = document.getElementById("help-banner");
31
+ const helpBannerCopy = document.getElementById("help-banner-copy");
32
+ const helpBannerDismiss = document.getElementById("help-banner-dismiss");
33
+ const viewModeToggleButton = document.querySelector('[data-action="toggle-view-mode"]');
34
+ const selectAgentButton = document.querySelector('[data-action="select-agent"]');
35
+ const newRequestToolButton = document.querySelector('[data-action="new-request"]');
36
+ const createCompanionDocToolButton = document.querySelector('[data-action="create-companion-doc"]');
37
+ const bootstrapLogicsButton = document.querySelector('[data-action="bootstrap-logics"]');
38
+ const updateLogicsKitButton = document.querySelector('[data-action="update-logics-kit"]');
39
+ const repairLogicsKitButton = document.querySelector('[data-action="repair-logics-kit"]');
40
+ const checkEnvironmentButton = document.querySelector('[data-action="check-environment"]');
41
+ const checkHybridRuntimeButton = document.querySelector('[data-action="check-hybrid-runtime"]');
42
+ const openHybridInsightsButton = document.querySelector('[data-action="open-hybrid-insights"]');
43
+ const openLogicsInsightsButton = document.querySelector('[data-action="open-logics-insights"]');
44
+ const openOnboardingButton = document.querySelector('[data-action="open-onboarding"]');
45
+ const assistCommitAllButton = document.querySelector('[data-action="assist-commit-all"]');
46
+ const assistNextStepButton = document.querySelector('[data-action="assist-next-step"]');
47
+ const assistTriageButton = document.querySelector('[data-action="assist-triage"]');
48
+ const assistDiffRiskButton = document.querySelector('[data-action="assist-diff-risk"]');
49
+ const assistSummarizeChangelogButton = document.querySelector('[data-action="assist-summarize-changelog"]');
50
+ const assistPrepareReleaseButton = document.querySelector('[data-action="assist-prepare-release"]');
51
+ const assistPublishReleaseButton = document.querySelector('[data-action="assist-publish-release"]');
52
+ const assistSummarizeValidationButton = document.querySelector('[data-action="assist-summarize-validation"]');
53
+ const assistValidationChecklistButton = document.querySelector('[data-action="assist-validation-checklist"]');
54
+ const assistDocConsistencyButton = document.querySelector('[data-action="assist-doc-consistency"]');
55
+ const changeProjectRootButton = document.querySelector('[data-action="change-project-root"]');
56
+ const resetProjectRootButton = document.querySelector('[data-action="reset-project-root"]');
57
+ const aboutButton = document.querySelector('[data-action="about"]');
58
+ const promoteButton = document.querySelector('[data-action="promote"]');
59
+ const markDoneButton = document.querySelector('[data-action="mark-done"]');
60
+ const markObsoleteButton = document.querySelector('[data-action="mark-obsolete"]');
61
+ const changeStatusButton = document.querySelector('[data-action="change-status"]');
62
+ const openButton = document.querySelector('[data-action="open"]');
63
+ const readButton = document.querySelector('[data-action="read"]');
64
+ const hideCompleteToggle = document.getElementById("hide-complete");
65
+ const hideProcessedRequestsToggle = document.getElementById("hide-processed-requests");
66
+ const hideSpecToggle = document.getElementById("hide-spec");
67
+ const showCompanionDocsToggle = document.getElementById("show-companion-docs");
68
+ const hideEmptyColumnsToggle = document.getElementById("hide-empty-columns");
69
+ const filterResetButton = document.getElementById("filter-reset");
70
+ const harnessBridge = window.__CDX_LOGICS_HARNESS__;
71
+ const isHarnessMode = Boolean(harnessBridge && harnessBridge.isHarness);
72
+
73
+ const defaultFilterState = {
74
+ hideCompleted: true,
75
+ hideProcessedRequests: true,
76
+ hideSpec: true,
77
+ showCompanionDocs: true,
78
+ hideEmptyColumns: true
79
+ };
80
+
81
+ let items = [];
82
+ let selectedId = null;
83
+ let changedPaths = [];
84
+ let activeAgent = null;
85
+ let lastInjectedContext = null;
86
+ let hideCompleted = defaultFilterState.hideCompleted;
87
+ let hideProcessedRequests = defaultFilterState.hideProcessedRequests;
88
+ let hideSpec = defaultFilterState.hideSpec;
89
+ let showCompanionDocs = defaultFilterState.showCompanionDocs;
90
+ let hideEmptyColumns = defaultFilterState.hideEmptyColumns;
91
+ let searchQuery = "";
92
+ let groupMode = "stage";
93
+ let sortMode = "updated-desc";
94
+ let activityPanelOpen = false;
95
+ let attentionOnly = false;
96
+ let helpDismissed = false;
97
+ let collapsedListStages = new Set();
98
+ const defaultCollapsedDetailSections = [
99
+ "attentionExplain",
100
+ "contextPack",
101
+ "dependencyMap",
102
+ "companionDocs",
103
+ "indicators",
104
+ "specs",
105
+ "primaryFlow",
106
+ "references",
107
+ "usedBy"
108
+ ];
109
+ let collapsedDetailSections = new Set(defaultCollapsedDetailSections);
110
+ let activeColumnMenu = null;
111
+ let activeColumnMenuButton = null;
112
+ let secondaryToolbarOpen = false;
113
+ let toolsPanelOpen = false;
114
+ let toolsPanelView = "workflow";
115
+ let canResetProjectRoot = false;
116
+ let canBootstrapLogics = false;
117
+ let bootstrapLogicsTitle = "Bootstrap Logics in this project";
118
+ let canLaunchCodex = false;
119
+ let launchCodexTitle = "Launch Codex with the globally published Logics kit";
120
+ let canLaunchClaude = false;
121
+ let launchClaudeTitle = "Launch Claude with the globally published Logics kit";
122
+ let canRepairLogicsKit = false;
123
+ let repairLogicsKitTitle = "Check current Logics runtime state and repair the shared kit publication or bridge files.";
124
+ let canPublishRelease = false;
125
+ let publishReleaseTitle = "Publish Release requires a GitHub-compatible repository.";
126
+ let shouldRecommendCheckEnvironment = false;
127
+ let activeWorkspaceRoot = null;
128
+ let persistedWorkspaceRoot = null;
129
+ const previousState = vscode.getState() || null;
130
+
131
+ const primaryStageOrder = ["request", "backlog", "task"];
132
+ const companionStageOrder = ["product", "architecture"];
133
+ const stackedQuery = window.matchMedia("(max-width: 900px)");
134
+ const compactListQuery = window.matchMedia("(max-width: 500px)");
135
+ const projectGithubUrl = "https://github.com/AlexAgo83/logics-manager";
136
+ const uiState = {
137
+ layoutMode: "horizontal",
138
+ detailsCollapsed: false,
139
+ viewMode: "board",
140
+ splitRatio: 0.6
141
+ };
142
+ const debugUi = (() => {
143
+ const globalFlag = Boolean(window.__CDX_LOGICS_DEBUG__);
144
+ let queryFlag = false;
145
+ try {
146
+ const params = new URLSearchParams(window.location.search);
147
+ const value = params.get("debug-ui");
148
+ queryFlag = value === "1" || value === "true";
149
+ } catch {
150
+ queryFlag = false;
151
+ }
152
+ return globalFlag || queryFlag;
153
+ })();
154
+ const modelApi = window.CdxLogicsModel || {};
155
+ const uiStatusFactory = window.createCdxLogicsUiStatusApi;
156
+ const harnessApiFactory = window.createCdxLogicsHarnessApi;
157
+ const layoutControllerFactory = window.createCdxLogicsLayoutController;
158
+ const hostApiFactory = window.createCdxLogicsHostApi;
159
+ const selectorFactory = window.createCdxLogicsWebviewSelectors;
160
+ const persistenceFactory = window.createCdxLogicsWebviewPersistence;
161
+ const chromeFactory = window.createCdxLogicsWebviewChrome;
162
+ const boardRendererFactory = window.createCdxLogicsBoardRenderer;
163
+ const detailsRendererFactory = window.createCdxLogicsDetailsRenderer;
164
+ const markdownApiFactory = window.createCdxLogicsMarkdownApi;
165
+ const mainInteractionHandlersFactory = window.createCdxLogicsMainInteractionHandlers;
166
+ const mainInteractionsFactory = window.createCdxLogicsMainInteractions;
167
+ const mainCoreFactory = window.createCdxLogicsMainCore;
168
+
169
+ function debugLog(eventName, payload = {}) {
170
+ if (!debugUi) {
171
+ return;
172
+ }
173
+ console.debug("[cdx-logics-webview]", eventName, payload);
174
+ }
175
+
176
+ function getSnapshot(scrollValues = { boardLeft: 0, boardTop: 0, detailsTop: 0 }) {
177
+ return {
178
+ workspaceRoot: activeWorkspaceRoot,
179
+ selectedId,
180
+ hideCompleted,
181
+ hideProcessedRequests,
182
+ hideSpec,
183
+ showCompanionDocs,
184
+ hideEmptyColumns,
185
+ searchQuery,
186
+ groupMode,
187
+ sortMode,
188
+ secondaryToolbarOpen,
189
+ activityPanelOpen,
190
+ attentionOnly,
191
+ helpDismissed,
192
+ collapsedListStages: Array.from(collapsedListStages),
193
+ detailsCollapsed: uiState.detailsCollapsed,
194
+ collapsedDetailSections: Array.from(collapsedDetailSections),
195
+ viewMode: uiState.viewMode,
196
+ splitRatio: uiState.splitRatio,
197
+ boardScrollLeft: scrollValues.boardLeft,
198
+ boardScrollTop: scrollValues.boardTop,
199
+ detailsScrollTop: scrollValues.detailsTop
200
+ };
201
+ }
202
+
203
+ function applyResetState({ defaultFilterState: nextDefaultFilterState, uiDefaults }) {
204
+ hideCompleted = nextDefaultFilterState.hideCompleted;
205
+ hideProcessedRequests = nextDefaultFilterState.hideProcessedRequests;
206
+ hideSpec = nextDefaultFilterState.hideSpec;
207
+ showCompanionDocs = nextDefaultFilterState.showCompanionDocs;
208
+ hideEmptyColumns = nextDefaultFilterState.hideEmptyColumns;
209
+ searchQuery = "";
210
+ groupMode = "stage";
211
+ sortMode = "updated-desc";
212
+ activityPanelOpen = false;
213
+ attentionOnly = false;
214
+ helpDismissed = false;
215
+ collapsedListStages = new Set();
216
+ collapsedDetailSections = new Set(defaultCollapsedDetailSections);
217
+ selectedId = null;
218
+ secondaryToolbarOpen = false;
219
+ toolsPanelOpen = false;
220
+ toolsPanelView = "workflow";
221
+ uiState.detailsCollapsed = uiDefaults.detailsCollapsed;
222
+ uiState.viewMode = uiDefaults.viewMode;
223
+ uiState.splitRatio = uiDefaults.splitRatio;
224
+ activeColumnMenu = null;
225
+ activeColumnMenuButton = null;
226
+ }
227
+
228
+ function applyPersistedState(nextState, nextScrollState) {
229
+ if (nextState && typeof nextState.hideCompleted === "boolean") {
230
+ hideCompleted = nextState.hideCompleted;
231
+ }
232
+ if (nextState && typeof nextState.hideProcessedRequests === "boolean") {
233
+ hideProcessedRequests = nextState.hideProcessedRequests;
234
+ } else if (nextState && typeof nextState.hideUsedRequests === "boolean") {
235
+ hideProcessedRequests = nextState.hideUsedRequests;
236
+ }
237
+ if (nextState && typeof nextState.hideSpec === "boolean") {
238
+ hideSpec = nextState.hideSpec;
239
+ }
240
+ if (nextState && typeof nextState.showCompanionDocs === "boolean") {
241
+ showCompanionDocs = nextState.showCompanionDocs;
242
+ }
243
+ if (nextState && typeof nextState.hideEmptyColumns === "boolean") {
244
+ hideEmptyColumns = nextState.hideEmptyColumns;
245
+ }
246
+ if (nextState && typeof nextState.searchQuery === "string") {
247
+ searchQuery = nextState.searchQuery;
248
+ }
249
+ if (nextState && typeof nextState.groupMode === "string") {
250
+ groupMode = nextState.groupMode;
251
+ }
252
+ if (nextState && typeof nextState.sortMode === "string") {
253
+ sortMode = nextState.sortMode;
254
+ }
255
+ if (nextState && typeof nextState.activityPanelOpen === "boolean") {
256
+ activityPanelOpen = nextState.activityPanelOpen;
257
+ }
258
+ if (nextState && typeof nextState.attentionOnly === "boolean") {
259
+ attentionOnly = nextState.attentionOnly;
260
+ }
261
+ if (nextState && typeof nextState.helpDismissed === "boolean") {
262
+ helpDismissed = nextState.helpDismissed;
263
+ }
264
+ if (nextState && typeof nextState.secondaryToolbarOpen === "boolean") {
265
+ secondaryToolbarOpen = nextState.secondaryToolbarOpen;
266
+ }
267
+ if (nextState && typeof nextState.toolsPanelView === "string") {
268
+ toolsPanelView = nextState.toolsPanelView;
269
+ }
270
+ if (nextState && typeof nextState.selectedId === "string") {
271
+ selectedId = nextState.selectedId;
272
+ }
273
+ if (nextState && typeof nextState.workspaceRoot === "string") {
274
+ persistedWorkspaceRoot = nextState.workspaceRoot;
275
+ }
276
+ if (nextState && Array.isArray(nextState.collapsedListStages)) {
277
+ collapsedListStages = new Set(nextState.collapsedListStages);
278
+ }
279
+ if (nextState && typeof nextState.detailsCollapsed === "boolean") {
280
+ uiState.detailsCollapsed = nextState.detailsCollapsed;
281
+ }
282
+ if (nextState && Array.isArray(nextState.collapsedDetailSections)) {
283
+ collapsedDetailSections = new Set(nextState.collapsedDetailSections);
284
+ }
285
+ if (nextState && (nextState.viewMode === "board" || nextState.viewMode === "list")) {
286
+ uiState.viewMode = nextState.viewMode;
287
+ }
288
+ if (nextState && typeof nextState.splitRatio === "number") {
289
+ uiState.splitRatio = nextState.splitRatio;
290
+ }
291
+ if (nextState && typeof nextState.boardScrollLeft === "number") {
292
+ nextScrollState.boardLeft = nextState.boardScrollLeft;
293
+ }
294
+ if (nextState && typeof nextState.boardScrollTop === "number") {
295
+ nextScrollState.boardTop = nextState.boardScrollTop;
296
+ }
297
+ if (nextState && typeof nextState.detailsScrollTop === "number") {
298
+ nextScrollState.detailsTop = nextState.detailsScrollTop;
299
+ }
300
+ }
301
+
302
+ const selectors =
303
+ typeof selectorFactory === "function"
304
+ ? selectorFactory({
305
+ modelApi,
306
+ primaryStageOrder,
307
+ companionStageOrder,
308
+ compactListQuery,
309
+ getItems: () => items,
310
+ getSelectedId: () => selectedId,
311
+ getActiveWorkspaceRoot: () => activeWorkspaceRoot,
312
+ getChangedPaths: () => changedPaths,
313
+ getActiveAgent: () => activeAgent,
314
+ getLastInjectedContext: () => lastInjectedContext,
315
+ getHideCompleted: () => hideCompleted,
316
+ getHideProcessedRequests: () => hideProcessedRequests,
317
+ getHideSpec: () => hideSpec,
318
+ getShowCompanionDocs: () => showCompanionDocs,
319
+ getHideEmptyColumns: () => hideEmptyColumns,
320
+ getSearchQuery: () => searchQuery,
321
+ getGroupMode: () => groupMode,
322
+ getSortMode: () => sortMode,
323
+ getAttentionOnly: () => attentionOnly,
324
+ getUiState: () => uiState
325
+ })
326
+ : null;
327
+
328
+ const {
329
+ canPromote,
330
+ isCompactListForced,
331
+ getEffectiveViewMode,
332
+ isListMode,
333
+ getStageLabel,
334
+ getStageHeading,
335
+ normalizeSearchValue,
336
+ getStatusValue,
337
+ getAttentionReasons,
338
+ getHealthSignals,
339
+ buildContextPack,
340
+ buildDependencyMap,
341
+ needsAttention,
342
+ getSuggestedActions,
343
+ getActivityEntries,
344
+ getHelpBannerMessage,
345
+ groupByStage,
346
+ getListGroups,
347
+ isVisible,
348
+ isPrimaryFlowStage,
349
+ isCompanionStage,
350
+ collectCompanionDocs,
351
+ collectSpecs,
352
+ collectPrimaryFlowItems,
353
+ findManagedItemByReference,
354
+ normalizeManagedDocValue,
355
+ getVisibleStages,
356
+ isComplete,
357
+ formatDate,
358
+ isProcessedWorkflowStatus,
359
+ collectLinkedWorkflowItems,
360
+ isRequestProcessed,
361
+ progressState,
362
+ getProgressValue
363
+ } = selectors || {};
364
+
365
+ const persistence =
366
+ typeof persistenceFactory === "function"
367
+ ? persistenceFactory({
368
+ vscode,
369
+ board,
370
+ detailsBody,
371
+ defaultFilterState,
372
+ getUiState: () => uiState,
373
+ getSnapshot,
374
+ applyResetState,
375
+ applyPersistedState
376
+ })
377
+ : null;
378
+
379
+ const captureScrollState =
380
+ persistence && typeof persistence.captureScrollState === "function"
381
+ ? () => persistence.captureScrollState()
382
+ : () => undefined;
383
+ const restoreScrollState =
384
+ persistence && typeof persistence.restoreScrollState === "function"
385
+ ? () => persistence.restoreScrollState()
386
+ : () => undefined;
387
+ const schedulePersistState =
388
+ persistence && typeof persistence.schedulePersistState === "function"
389
+ ? () => persistence.schedulePersistState()
390
+ : () => undefined;
391
+ const resetPersistedUiState =
392
+ persistence && typeof persistence.resetPersistedUiState === "function"
393
+ ? () => persistence.resetPersistedUiState()
394
+ : () => undefined;
395
+ const persistState =
396
+ persistence && typeof persistence.persistState === "function"
397
+ ? () => persistence.persistState()
398
+ : () => undefined;
399
+ const persistenceHydratePersistedState =
400
+ persistence && typeof persistence.hydrate === "function"
401
+ ? (state) => persistence.hydrate(state)
402
+ : () => undefined;
403
+
404
+ const state = {};
405
+ Object.defineProperties(state, {
406
+ items: { get: () => items, set: (value) => { items = value; } },
407
+ selectedId: { get: () => selectedId, set: (value) => { selectedId = value; } },
408
+ changedPaths: { get: () => changedPaths, set: (value) => { changedPaths = value; } },
409
+ activeAgent: { get: () => activeAgent, set: (value) => { activeAgent = value; } },
410
+ lastInjectedContext: { get: () => lastInjectedContext, set: (value) => { lastInjectedContext = value; } },
411
+ hideCompleted: { get: () => hideCompleted, set: (value) => { hideCompleted = value; } },
412
+ hideProcessedRequests: { get: () => hideProcessedRequests, set: (value) => { hideProcessedRequests = value; } },
413
+ hideSpec: { get: () => hideSpec, set: (value) => { hideSpec = value; } },
414
+ showCompanionDocs: { get: () => showCompanionDocs, set: (value) => { showCompanionDocs = value; } },
415
+ hideEmptyColumns: { get: () => hideEmptyColumns, set: (value) => { hideEmptyColumns = value; } },
416
+ searchQuery: { get: () => searchQuery, set: (value) => { searchQuery = value; } },
417
+ groupMode: { get: () => groupMode, set: (value) => { groupMode = value; } },
418
+ sortMode: { get: () => sortMode, set: (value) => { sortMode = value; } },
419
+ activityPanelOpen: { get: () => activityPanelOpen, set: (value) => { activityPanelOpen = value; } },
420
+ attentionOnly: { get: () => attentionOnly, set: (value) => { attentionOnly = value; } },
421
+ helpDismissed: { get: () => helpDismissed, set: (value) => { helpDismissed = value; } },
422
+ collapsedListStages: { get: () => collapsedListStages, set: (value) => { collapsedListStages = value; } },
423
+ collapsedDetailSections: { get: () => collapsedDetailSections, set: (value) => { collapsedDetailSections = value; } },
424
+ activeColumnMenu: { get: () => activeColumnMenu, set: (value) => { activeColumnMenu = value; } },
425
+ activeColumnMenuButton: { get: () => activeColumnMenuButton, set: (value) => { activeColumnMenuButton = value; } },
426
+ secondaryToolbarOpen: { get: () => secondaryToolbarOpen, set: (value) => { secondaryToolbarOpen = value; } },
427
+ toolsPanelOpen: { get: () => toolsPanelOpen, set: (value) => { toolsPanelOpen = value; } },
428
+ toolsPanelView: { get: () => toolsPanelView, set: (value) => { toolsPanelView = value; } },
429
+ canResetProjectRoot: { get: () => canResetProjectRoot, set: (value) => { canResetProjectRoot = value; } },
430
+ canBootstrapLogics: { get: () => canBootstrapLogics, set: (value) => { canBootstrapLogics = value; } },
431
+ bootstrapLogicsTitle: { get: () => bootstrapLogicsTitle, set: (value) => { bootstrapLogicsTitle = value; } },
432
+ canLaunchCodex: { get: () => canLaunchCodex, set: (value) => { canLaunchCodex = value; } },
433
+ launchCodexTitle: { get: () => launchCodexTitle, set: (value) => { launchCodexTitle = value; } },
434
+ canLaunchClaude: { get: () => canLaunchClaude, set: (value) => { canLaunchClaude = value; } },
435
+ launchClaudeTitle: { get: () => launchClaudeTitle, set: (value) => { launchClaudeTitle = value; } },
436
+ canRepairLogicsKit: { get: () => canRepairLogicsKit, set: (value) => { canRepairLogicsKit = value; } },
437
+ repairLogicsKitTitle: { get: () => repairLogicsKitTitle, set: (value) => { repairLogicsKitTitle = value; } },
438
+ canPublishRelease: { get: () => canPublishRelease, set: (value) => { canPublishRelease = value; } },
439
+ publishReleaseTitle: { get: () => publishReleaseTitle, set: (value) => { publishReleaseTitle = value; } },
440
+ shouldRecommendCheckEnvironment: { get: () => shouldRecommendCheckEnvironment, set: (value) => { shouldRecommendCheckEnvironment = value; } },
441
+ activeWorkspaceRoot: { get: () => activeWorkspaceRoot, set: (value) => { activeWorkspaceRoot = value; } },
442
+ persistedWorkspaceRoot: { get: () => persistedWorkspaceRoot, set: (value) => { persistedWorkspaceRoot = value; } },
443
+ uiState: { get: () => uiState },
444
+ scrollState: { get: () => ({ boardLeft: 0, boardTop: 0, detailsTop: 0 }), set: () => undefined }
445
+ });
446
+
447
+ let mainCore;
448
+
449
+ const chrome =
450
+ typeof chromeFactory === "function"
451
+ ? chromeFactory({
452
+ activityPanel,
453
+ activityToggle,
454
+ headerLogicsInsightsButton,
455
+ attentionToggle,
456
+ bootstrapLogicsButton,
457
+ repairLogicsKitButton,
458
+ assistPublishReleaseButton,
459
+ filterPanel,
460
+ filterToggle,
461
+ toolsToggle,
462
+ groupBySelect,
463
+ helpBanner,
464
+ helpBannerCopy,
465
+ hideCompleteToggle,
466
+ hideEmptyColumnsToggle,
467
+ hideProcessedRequestsToggle,
468
+ hideSpecToggle,
469
+ markDoneButton,
470
+ markObsoleteButton,
471
+ changeStatusButton,
472
+ openButton,
473
+ promoteButton,
474
+ readButton,
475
+ getToolsPanelView: () => toolsPanelView,
476
+ resetProjectRootButton,
477
+ searchInput,
478
+ showCompanionDocsToggle,
479
+ sortBySelect,
480
+ toolsPanel,
481
+ toolsToggle,
482
+ viewModeToggleButton,
483
+ defaultFilterState,
484
+ canPromote,
485
+ getActivityEntries,
486
+ getAttentionOnly: () => attentionOnly,
487
+ getActivityPanelOpen: () => activityPanelOpen,
488
+ getCanBootstrapLogics: () => canBootstrapLogics,
489
+ getBootstrapLogicsTitle: () => bootstrapLogicsTitle,
490
+ getCanResetProjectRoot: () => canResetProjectRoot,
491
+ getCanLaunchCodex: () => canLaunchCodex,
492
+ getLaunchCodexTitle: () => launchCodexTitle,
493
+ getCanLaunchClaude: () => canLaunchClaude,
494
+ getLaunchClaudeTitle: () => launchClaudeTitle,
495
+ getCanRepairLogicsKit: () => canRepairLogicsKit,
496
+ getRepairLogicsKitTitle: () => repairLogicsKitTitle,
497
+ getCanPublishRelease: () => canPublishRelease,
498
+ getPublishReleaseTitle: () => publishReleaseTitle,
499
+ getShouldRecommendCheckEnvironment: () => shouldRecommendCheckEnvironment,
500
+ getEffectiveViewMode,
501
+ getGroupMode: () => groupMode,
502
+ getHelpBannerMessage,
503
+ getHelpDismissed: () => helpDismissed,
504
+ getHideCompleted: () => hideCompleted,
505
+ getHideEmptyColumns: () => hideEmptyColumns,
506
+ getHideProcessedRequests: () => hideProcessedRequests,
507
+ getHideSpec: () => hideSpec,
508
+ getIsListMode: () => isListMode(),
509
+ getSearchQuery: () => searchQuery,
510
+ getSecondaryToolbarOpen: () => secondaryToolbarOpen,
511
+ getShowCompanionDocs: () => showCompanionDocs,
512
+ getSortMode: () => sortMode,
513
+ getStageLabel,
514
+ getToolsPanelOpen: () => toolsPanelOpen,
515
+ getSelectedItem,
516
+ isCompactListForced,
517
+ normalizeSearchValue,
518
+ readItemAndRender(nextId) {
519
+ selectedId = nextId;
520
+ render();
521
+ openSelectedItem("read");
522
+ },
523
+ selectItemAndRender(nextId) {
524
+ selectedId = nextId;
525
+ render();
526
+ }
527
+ })
528
+ : null;
529
+
530
+ const updateViewModeToggle =
531
+ chrome && typeof chrome.updateViewModeToggle === "function" ? () => chrome.updateViewModeToggle() : () => undefined;
532
+ const renderActivityPanel =
533
+ chrome && typeof chrome.renderActivityPanel === "function" ? () => chrome.renderActivityPanel() : () => undefined;
534
+ const renderHelpBanner =
535
+ chrome && typeof chrome.renderHelpBanner === "function" ? () => chrome.renderHelpBanner() : () => undefined;
536
+ const updateButtons =
537
+ chrome && typeof chrome.updateButtons === "function" ? () => chrome.updateButtons() : () => undefined;
538
+ const hasNonDefaultSecondaryControls =
539
+ chrome && typeof chrome.hasNonDefaultSecondaryControls === "function"
540
+ ? () => chrome.hasNonDefaultSecondaryControls()
541
+ : () => false;
542
+ const updateFilterState =
543
+ chrome && typeof chrome.updateFilterState === "function" ? () => chrome.updateFilterState() : () => undefined;
544
+ const syncChromeInputs =
545
+ chrome && typeof chrome.syncInputs === "function" ? () => chrome.syncInputs() : () => undefined;
546
+ const applyToolsPanelOpen =
547
+ chrome && typeof chrome.setToolsPanelOpen === "function"
548
+ ? (viewName, isOpen) => chrome.setToolsPanelOpen(viewName, isOpen)
549
+ : () => undefined;
550
+ const setControlDescription =
551
+ chrome && typeof chrome.setControlDescription === "function"
552
+ ? (element, label) => chrome.setControlDescription(element, label)
553
+ : () => undefined;
554
+
555
+ function getSelectedItem() {
556
+ return items.find((item) => item.id === selectedId) || null;
557
+ }
558
+
559
+ function buildColumnMenu() {
560
+ const menu = document.createElement("div");
561
+ menu.className = "column__menu";
562
+ menu.setAttribute("role", "menu");
563
+ const options = [
564
+ { label: "Open", action: "open" },
565
+ { label: "Read", action: "read" },
566
+ { label: "Promote", action: "promote" }
567
+ ];
568
+ for (const option of options) {
569
+ const item = document.createElement("button");
570
+ item.type = "button";
571
+ item.className = "column__menu-item";
572
+ item.textContent = option.label;
573
+ item.setAttribute("role", "menuitem");
574
+ item.addEventListener("click", () => {
575
+ const selectedItem = getSelectedItem();
576
+ if (selectedItem) {
577
+ hostApi[option.action](selectedItem);
578
+ }
579
+ closeColumnMenu();
580
+ });
581
+ menu.appendChild(item);
582
+ }
583
+ return menu;
584
+ }
585
+
586
+ function closeColumnMenu() {
587
+ if (activeColumnMenu) {
588
+ activeColumnMenu.remove();
589
+ }
590
+ if (activeColumnMenuButton) {
591
+ activeColumnMenuButton.setAttribute("aria-expanded", "false");
592
+ }
593
+ activeColumnMenu = null;
594
+ activeColumnMenuButton = null;
595
+ }
596
+
597
+ function toggleColumnMenu(button) {
598
+ if (activeColumnMenuButton === button) {
599
+ closeColumnMenu();
600
+ return;
601
+ }
602
+ closeColumnMenu();
603
+ const menu = buildColumnMenu();
604
+ activeColumnMenu = menu;
605
+ activeColumnMenuButton = button;
606
+ button.setAttribute("aria-expanded", "true");
607
+ button.parentElement?.appendChild(menu);
608
+ }
609
+
610
+ let setState = () => undefined;
611
+ let render = () => undefined;
612
+ let restoreDefaultFilters = () => undefined;
613
+ let setFilterPanelOpen = () => undefined;
614
+ let setToolsPanelOpen = () => undefined;
615
+ let openSelectedItem = () => undefined;
616
+ let handleChangeProjectRoot = async () => undefined;
617
+ let handleResetProjectRoot = () => undefined;
618
+ let handleBootstrapLogics = () => undefined;
619
+ let handleAbout = () => undefined;
620
+ let handleHostMessage = () => undefined;
621
+ let renderBoardErrorState = () => undefined;
622
+ let handleDocumentClick = () => undefined;
623
+ let handleDocumentKeydown = () => undefined;
624
+ let handleSplitterKeydown = () => undefined;
625
+ let handleResponsiveLayoutChange = () => undefined;
626
+ let hydratePersistedState = () => undefined;
627
+
628
+ const markdownApi = typeof markdownApiFactory === "function" ? markdownApiFactory() : null;
629
+
630
+ function escapeHtml(value) {
631
+ if (markdownApi && typeof markdownApi.escapeHtml === "function") {
632
+ return markdownApi.escapeHtml(value);
633
+ }
634
+ return String(value ?? "");
635
+ }
636
+ const uiStatus = typeof uiStatusFactory === "function"
637
+ ? uiStatusFactory({
638
+ documentRef: document,
639
+ layout,
640
+ harnessBridge
641
+ })
642
+ : null;
643
+ const showStatus =
644
+ uiStatus && typeof uiStatus.showStatus === "function"
645
+ ? (message, tone) => uiStatus.showStatus(message, tone)
646
+ : () => undefined;
647
+ const harnessApi = typeof harnessApiFactory === "function"
648
+ ? harnessApiFactory({
649
+ isHarnessMode,
650
+ harnessBridge,
651
+ markdownApi,
652
+ escapeHtml,
653
+ showStatus,
654
+ projectGithubUrl
655
+ })
656
+ : null;
657
+
658
+ const hostApi = hostApiFactory({
659
+ vscode,
660
+ debugLog,
661
+ showStatus,
662
+ isHarnessMode,
663
+ handleHarnessChangeProjectRoot: () =>
664
+ harnessApi && typeof harnessApi.handleHarnessChangeProjectRoot === "function"
665
+ ? harnessApi.handleHarnessChangeProjectRoot()
666
+ : Promise.resolve(),
667
+ applyHarnessRoot: (rootLabel) => {
668
+ if (harnessApi && typeof harnessApi.applyHarnessRoot === "function") {
669
+ harnessApi.applyHarnessRoot(rootLabel);
670
+ }
671
+ },
672
+ openHarnessItem: (item, mode) => {
673
+ if (harnessApi && typeof harnessApi.openHarnessItem === "function") {
674
+ harnessApi.openHarnessItem(item, mode);
675
+ }
676
+ },
677
+ harnessBridge,
678
+ setCanResetProjectRoot(value) {
679
+ canResetProjectRoot = value;
680
+ if (harnessApi && typeof harnessApi.setCanResetProjectRoot === "function") {
681
+ harnessApi.setCanResetProjectRoot(value);
682
+ }
683
+ },
684
+ projectGithubUrl
685
+ });
686
+
687
+ const boardRenderer = typeof boardRendererFactory === "function"
688
+ ? boardRendererFactory({
689
+ board,
690
+ hostApi,
691
+ getItems: () => items,
692
+ getTotalItemCount: () => items.length,
693
+ getSelectedId: () => selectedId,
694
+ setSelectedId(value) {
695
+ selectedId = value;
696
+ },
697
+ isListMode,
698
+ getVisibleStages,
699
+ groupByStage,
700
+ getListGroups,
701
+ isVisible,
702
+ isPrimaryFlowStage,
703
+ isRequestProcessed,
704
+ getStageHeading,
705
+ getStageLabel,
706
+ collectCompanionDocs,
707
+ collectSpecs,
708
+ collectPrimaryFlowItems,
709
+ getAttentionReasons,
710
+ getHealthSignals,
711
+ getSuggestedActions,
712
+ progressState,
713
+ getProgressValue,
714
+ isComplete,
715
+ render: () => render(),
716
+ openSelectedItem: (mode) => openSelectedItem(mode),
717
+ closeColumnMenu,
718
+ toggleColumnMenu,
719
+ persistState,
720
+ getCollapsedListStages: () => collapsedListStages,
721
+ getHideCompleted: () => hideCompleted,
722
+ getHideProcessedRequests: () => hideProcessedRequests,
723
+ getHideSpec: () => hideSpec,
724
+ getShowCompanionDocs: () => showCompanionDocs,
725
+ getHideEmptyColumns: () => hideEmptyColumns,
726
+ getSearchQuery: () => searchQuery,
727
+ getGroupMode: () => groupMode,
728
+ getSortMode: () => sortMode,
729
+ getAttentionOnly: () => attentionOnly
730
+ })
731
+ : null;
732
+
733
+ const detailsRenderer = typeof detailsRendererFactory === "function"
734
+ ? detailsRendererFactory({
735
+ detailsBody,
736
+ detailsTitle,
737
+ detailsEyebrow,
738
+ hostApi,
739
+ getItems: () => items,
740
+ getSelectedId: () => selectedId,
741
+ getActiveWorkspaceRoot: () => activeWorkspaceRoot,
742
+ getChangedPaths: () => changedPaths,
743
+ getActiveAgent: () => activeAgent,
744
+ getLastInjectedContext: () => lastInjectedContext,
745
+ getCollapsedDetailSections: () => collapsedDetailSections,
746
+ persistState,
747
+ getStageLabel,
748
+ isPrimaryFlowStage,
749
+ collectCompanionDocs,
750
+ collectSpecs,
751
+ collectPrimaryFlowItems,
752
+ getAttentionReasons,
753
+ buildContextPack,
754
+ buildDependencyMap,
755
+ findManagedItemByReference,
756
+ formatDate,
757
+ setLastInjectedContext(nextValue) {
758
+ lastInjectedContext = nextValue;
759
+ },
760
+ selectItem(nextId) {
761
+ selectedId = nextId;
762
+ render();
763
+ }
764
+ })
765
+ : null;
766
+
767
+ const layoutController = typeof layoutControllerFactory === "function"
768
+ ? layoutControllerFactory({
769
+ layout,
770
+ mainPane,
771
+ board,
772
+ activityPanel,
773
+ details,
774
+ splitter,
775
+ stackedQuery,
776
+ uiState,
777
+ persistState,
778
+ debugLog,
779
+ isDetailsCollapsed: () => uiState.detailsCollapsed,
780
+ getPrimaryPaneScrollHeight: () => {
781
+ if (activityPanelOpen && activityPanel) {
782
+ return activityPanel.scrollHeight || 0;
783
+ }
784
+ return board ? board.scrollHeight || 0 : 0;
785
+ }
786
+ })
787
+ : null;
788
+
789
+ mainCore =
790
+ typeof mainCoreFactory === "function"
791
+ ? mainCoreFactory({
792
+ state,
793
+ board,
794
+ mainPane,
795
+ layout,
796
+ splitter,
797
+ details,
798
+ detailsBody,
799
+ detailsToggle,
800
+ detailsTitle,
801
+ filterPanel,
802
+ toolsPanel,
803
+ filterToggle,
804
+ toolsToggle,
805
+ viewModeToggleButton,
806
+ projectGithubUrl,
807
+ stackedQuery,
808
+ compactListQuery,
809
+ hostApi,
810
+ layoutController,
811
+ boardRenderer,
812
+ detailsRenderer,
813
+ chrome,
814
+ renderActivityPanel,
815
+ renderHelpBanner,
816
+ updateButtons,
817
+ updateViewModeToggle,
818
+ updateFilterState,
819
+ syncChromeInputs,
820
+ captureScrollState,
821
+ restoreScrollState,
822
+ schedulePersistState,
823
+ resetPersistedUiState,
824
+ persistState,
825
+ applyToolsPanelOpen,
826
+ isListMode,
827
+ isVisible,
828
+ getVisibleStages,
829
+ groupByStage,
830
+ getListGroups,
831
+ getAttentionReasons,
832
+ getStageLabel,
833
+ isPrimaryFlowStage,
834
+ isRequestProcessed,
835
+ buildContextPack,
836
+ buildDependencyMap,
837
+ findManagedItemByReference,
838
+ formatDate,
839
+ collectCompanionDocs,
840
+ collectSpecs,
841
+ collectPrimaryFlowItems,
842
+ getCanResetProjectRoot: () => canResetProjectRoot,
843
+ setCanResetProjectRoot(value) {
844
+ canResetProjectRoot = value;
845
+ },
846
+ getCanBootstrapLogics: () => canBootstrapLogics,
847
+ setCanBootstrapLogics(value) {
848
+ canBootstrapLogics = value;
849
+ },
850
+ setBootstrapLogicsTitle(value) {
851
+ bootstrapLogicsTitle = value;
852
+ },
853
+ getCanLaunchCodex: () => canLaunchCodex,
854
+ setCanLaunchCodex(value) {
855
+ canLaunchCodex = value;
856
+ },
857
+ setLaunchCodexTitle(value) {
858
+ launchCodexTitle = value;
859
+ },
860
+ getCanLaunchClaude: () => canLaunchClaude,
861
+ setCanLaunchClaude(value) {
862
+ canLaunchClaude = value;
863
+ },
864
+ setLaunchClaudeTitle(value) {
865
+ launchClaudeTitle = value;
866
+ },
867
+ getCanRepairLogicsKit: () => canRepairLogicsKit,
868
+ setCanRepairLogicsKit(value) {
869
+ canRepairLogicsKit = value;
870
+ },
871
+ setRepairLogicsKitTitle(value) {
872
+ repairLogicsKitTitle = value;
873
+ },
874
+ getCanPublishRelease: () => canPublishRelease,
875
+ setCanPublishRelease(value) {
876
+ canPublishRelease = value;
877
+ },
878
+ setPublishReleaseTitle(value) {
879
+ publishReleaseTitle = value;
880
+ },
881
+ getShouldRecommendCheckEnvironment: () => shouldRecommendCheckEnvironment,
882
+ setShouldRecommendCheckEnvironment(value) {
883
+ shouldRecommendCheckEnvironment = value;
884
+ },
885
+ defaultFilterState,
886
+ hydratePersistedState: persistenceHydratePersistedState,
887
+ harnessApi
888
+ })
889
+ : null;
890
+
891
+ ({
892
+ setState,
893
+ render,
894
+ restoreDefaultFilters,
895
+ setFilterPanelOpen,
896
+ setToolsPanelOpen,
897
+ openSelectedItem,
898
+ handleChangeProjectRoot,
899
+ handleResetProjectRoot,
900
+ handleBootstrapLogics,
901
+ handleAbout,
902
+ handleHostMessage,
903
+ renderBoardErrorState,
904
+ handleDocumentClick,
905
+ handleDocumentKeydown,
906
+ handleSplitterKeydown,
907
+ handleResponsiveLayoutChange,
908
+ hydratePersistedState
909
+ } = mainCore || {});
910
+
911
+ hydratePersistedState(previousState);
912
+ if (!previousState || typeof previousState.detailsCollapsed !== "boolean") {
913
+ uiState.detailsCollapsed = uiState.viewMode === "list" || compactListQuery.matches;
914
+ }
915
+
916
+ const interactionHandlers =
917
+ typeof mainInteractionHandlersFactory === "function"
918
+ ? mainInteractionHandlersFactory({
919
+ core: mainCore,
920
+ hostApi,
921
+ layoutController,
922
+ stackedQuery,
923
+ compactListQuery,
924
+ state
925
+ })
926
+ : {};
927
+
928
+ const interactions =
929
+ typeof mainInteractionsFactory === "function"
930
+ ? mainInteractionsFactory({
931
+ activityToggle,
932
+ headerLogicsInsightsButton,
933
+ attentionToggle,
934
+ board,
935
+ assistCommitAllButton,
936
+ assistNextStepButton,
937
+ assistTriageButton,
938
+ assistDiffRiskButton,
939
+ assistSummarizeChangelogButton,
940
+ assistPrepareReleaseButton,
941
+ assistPublishReleaseButton,
942
+ assistSummarizeValidationButton,
943
+ assistValidationChecklistButton,
944
+ assistDocConsistencyButton,
945
+ bootstrapLogicsButton,
946
+ checkHybridRuntimeButton,
947
+ checkEnvironmentButton,
948
+ openHybridInsightsButton,
949
+ openLogicsInsightsButton,
950
+ openOnboardingButton,
951
+ changeProjectRootButton,
952
+ compactListQuery,
953
+ createCompanionDocToolButton,
954
+ detailsBody,
955
+ detailsToggle,
956
+ filterPanel,
957
+ filterResetButton,
958
+ filterToggle,
959
+ toolsToggle,
960
+ groupBySelect,
961
+ helpBannerDismiss,
962
+ hideCompleteToggle,
963
+ hideEmptyColumnsToggle,
964
+ hideProcessedRequestsToggle,
965
+ hideSpecToggle,
966
+ layoutController,
967
+ repairLogicsKitButton,
968
+ mainPane,
969
+ markDoneButton,
970
+ markObsoleteButton,
971
+ changeStatusButton,
972
+ newRequestToolButton,
973
+ openButton,
974
+ promoteButton,
975
+ readButton,
976
+ resetProjectRootButton,
977
+ searchInput,
978
+ selectAgentButton,
979
+ setControlDescription,
980
+ showCompanionDocsToggle,
981
+ sortBySelect,
982
+ splitter,
983
+ stackedQuery,
984
+ toolsPanel,
985
+ updateLogicsKitButton,
986
+ viewModeToggleButton,
987
+ aboutButton,
988
+ ...interactionHandlers
989
+ })
990
+ : null;
991
+
992
+ if (interactions && typeof interactions.attach === "function") {
993
+ interactions.attach();
994
+ }
995
+
996
+ if (typeof setToolsPanelOpen === "function") {
997
+ setToolsPanelOpen(toolsPanelView, toolsPanelOpen);
998
+ }
999
+
1000
+ if (layoutController && typeof layoutController.updateLayoutMode === "function") {
1001
+ layoutController.updateLayoutMode();
1002
+ }
1003
+ debugLog("webview:init", { mode: isHarnessMode ? "harness" : "vscode" });
1004
+ hostApi.ready();
1005
+ })();