codex-agent-view 0.5.5 → 0.5.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/.codex-plugin/plugin.json +1 -1
- package/README.ko.md +24 -6
- package/README.md +24 -6
- package/bin/codex-agent-view.mjs +63 -15
- package/package.json +1 -1
- package/public/app.js +79 -17
- package/public/styles.css +23 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-agent-view",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "A read-only Codex plugin for monitoring live tasks and subagents in your browser. Open each view with one lightweight @codex-agent-view invocation. Once open, live monitoring runs locally with no additional model calls.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Junho Yoon",
|
package/README.ko.md
CHANGED
|
@@ -13,19 +13,36 @@ Codex를 대체하거나 작업·에이전트를 제어하지 않으며, 외부
|
|
|
13
13
|
일반 터미널에서 현재 릴리스를 설치합니다.
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
codex --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
PATH에서 선택되는 `codex` executable을 npm으로 설치했다면 다음과 같이 업데이트한 뒤 선택된 version을 다시 확인합니다.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install --global @openai/codex@latest
|
|
23
|
+
codex --version
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Codex를 다른 install channel로 설치했다면 그 channel에서 업데이트하세요. 그다음 plugin package를 설치합니다.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install --global codex-agent-view@0.5.6
|
|
17
30
|
codex-agent-view install
|
|
18
31
|
```
|
|
19
32
|
|
|
20
|
-
|
|
33
|
+
`0.5.6` installer는 등록 전에 포함된 plugin을 marketplace의 strict subdirectory로 복사하여 `0.5.5`의 marketplace-root discovery 실패를 피합니다.
|
|
34
|
+
|
|
35
|
+
npm 명령은 package를 설치합니다. `codex-agent-view install`은 포함된 local Codex plugin을 복사하고 명시적으로 등록합니다. `npm install`만으로는 Codex 설정을 바꾸지 않으며, 이 package에는 설정을 자동 변경하는 `postinstall` script가 없습니다.
|
|
21
36
|
|
|
22
37
|
설치 후에는 다음 순서를 따릅니다.
|
|
23
38
|
|
|
24
|
-
1.
|
|
25
|
-
2.
|
|
26
|
-
3.
|
|
39
|
+
1. Codex 앱의 **Plugins** 화면에서 **Codex Agent View**가 설치·활성화됐는지 확인합니다.
|
|
40
|
+
2. **Hooks** 영역에서 **검토(Review)**를 선택해 `hooks/hooks.json`과 `node "${PLUGIN_ROOT}/scripts/send-hook.mjs"` 명령을 확인한 뒤, 현재 정의에 **모두 신뢰하기(Trust all)**를 선택합니다. 앱에 Hook 검토 UI가 없을 때만 interactive Codex CLI의 `/hooks`를 사용합니다.
|
|
41
|
+
3. Codex 앱을 완전히 종료한 뒤 다시 엽니다.
|
|
27
42
|
4. Codex 앱에서 새 작업을 만듭니다. 설치 전에 지나간 event는 재생되지 않습니다.
|
|
28
43
|
|
|
44
|
+
현재 programmatic plugin status에는 저장된 Hook 신뢰 상태가 노출되지 않으므로 browser와 `doctor`는 승인 여부를 확인할 수 없습니다. Codex 앱이나 interactive `/hooks` UI에서 직접 확인하세요.
|
|
45
|
+
|
|
29
46
|
## 사용
|
|
30
47
|
|
|
31
48
|
Codex 앱의 작업 입력창에서 다음 plugin을 선택해 그대로 전송합니다.
|
|
@@ -40,6 +57,7 @@ Codex 앱의 작업 입력창에서 다음 plugin을 선택해 그대로 전송
|
|
|
40
57
|
- 터미널에서 monitor를 시작하지 않습니다.
|
|
41
58
|
- localhost 주소를 복사하거나 관리하지 않습니다.
|
|
42
59
|
- 브라우저 탭을 닫아도 Codex 작업은 중단되지 않습니다. 새 인증 탭이 필요하면 `@codex-agent-view`를 다시 실행합니다.
|
|
60
|
+
- Viewer를 연 작업 자체는 화면에서 숨겨지므로, 확인하려는 작업과 별도의 viewer 작업에서 실행합니다.
|
|
43
61
|
|
|
44
62
|
공개 Codex plugin API는 이 흐름을 위한 앱 sidebar나 in-app panel 자동 생성을 안정적으로 제공하지 않으므로, 운영체제 기본 브라우저가 지원하는 표시 화면입니다.
|
|
45
63
|
|
|
@@ -94,7 +112,7 @@ codex-agent-view uninstall --purge
|
|
|
94
112
|
|
|
95
113
|
## 릴리스 및 프로젝트 문서
|
|
96
114
|
|
|
97
|
-
Registry digest,
|
|
115
|
+
Registry digest, 이 기기의 compatible-CLI reinstall, CI, tag와 GitHub Release를 포함한 공개·검증 증거는 변경할 수 없는 npm package README 밖의 [배포 문서](docs/distribution.md)에 기록합니다. 이 검증은 clean cross-device first install을 확인하지 않았으며, 위 호환성 실패는 별도 사실로 기록합니다.
|
|
98
116
|
|
|
99
117
|
npm 공개와 Universal Plugins Directory 제출은 별도 절차입니다. Directory validator 호환성, portal/reviewer acceptance, 검색 노출과 promptless plugin-card Quick start 동작은 아직 확인하지 않았으며 이 문서에서 지원을 주장하지 않습니다.
|
|
100
118
|
|
package/README.md
CHANGED
|
@@ -13,19 +13,36 @@ It does not replace Codex, control tasks or agents, run a hosted service, send t
|
|
|
13
13
|
Install the current release from a regular terminal:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
|
|
16
|
+
codex --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If the `codex` executable on your PATH was installed through npm, update it and verify the selected version again:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install --global @openai/codex@latest
|
|
23
|
+
codex --version
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If Codex came from another install channel, update it through that channel instead. Then install the plugin package:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install --global codex-agent-view@0.5.6
|
|
17
30
|
codex-agent-view install
|
|
18
31
|
```
|
|
19
32
|
|
|
20
|
-
The
|
|
33
|
+
The `0.5.6` installer copies the bundled plugin into a strict marketplace subdirectory before registration, avoiding the marketplace-root discovery failure in `0.5.5`.
|
|
34
|
+
|
|
35
|
+
The npm command installs the package. `codex-agent-view install` copies and explicitly registers its bundled local Codex plugin. `npm install` alone does not modify Codex settings, and this package has no `postinstall` script that does so.
|
|
21
36
|
|
|
22
37
|
Then:
|
|
23
38
|
|
|
24
|
-
1.
|
|
25
|
-
2. In
|
|
26
|
-
3.
|
|
39
|
+
1. In the Codex app's **Plugins** screen, confirm that **Codex Agent View** is installed and enabled.
|
|
40
|
+
2. In its **Hooks** section, choose **Review**, inspect `hooks/hooks.json` and the `node "${PLUGIN_ROOT}/scripts/send-hook.mjs"` command, then choose **Trust all** for the current definitions. Only if the app has no hook-review UI, use `/hooks` in the interactive Codex CLI.
|
|
41
|
+
3. Quit Codex completely and reopen it.
|
|
27
42
|
4. Create a new Codex task. Events from before installation are not replayed.
|
|
28
43
|
|
|
44
|
+
Persisted hook trust is not exposed by the current programmatic plugin status, so the browser and `doctor` cannot confirm that approval; verify it in the Codex app or interactive `/hooks` UI.
|
|
45
|
+
|
|
29
46
|
## Use
|
|
30
47
|
|
|
31
48
|
In a Codex app task, select and send:
|
|
@@ -40,6 +57,7 @@ That is the whole normal-use command. The plugin prepares or reuses its local mo
|
|
|
40
57
|
- Do not start the monitor in a terminal.
|
|
41
58
|
- Do not copy or manage a localhost URL.
|
|
42
59
|
- Closing the browser tab does not stop Codex work. Invoke `@codex-agent-view` again when you want a new authenticated tab.
|
|
60
|
+
- The task used to open the viewer is hidden from the view itself, so use a separate viewer task to monitor the work you care about.
|
|
43
61
|
|
|
44
62
|
The public Codex plugin API does not provide a reliable automatic app sidebar or in-app panel for this workflow, so the default browser is the supported display surface.
|
|
45
63
|
|
|
@@ -94,7 +112,7 @@ codex-agent-view uninstall --purge
|
|
|
94
112
|
|
|
95
113
|
## Release and project documentation
|
|
96
114
|
|
|
97
|
-
Release publication and verification evidence is recorded outside the immutable npm package README in [Distribution](docs/distribution.md), including registry digests,
|
|
115
|
+
Release publication and verification evidence is recorded outside the immutable npm package README in [Distribution](docs/distribution.md), including registry digests, this-device compatible-CLI reinstall checks, CI, tags, and GitHub Releases. Those checks did not verify a clean cross-device first install; the compatibility failure above is now recorded separately.
|
|
98
116
|
|
|
99
117
|
npm publication is separate from submission to the Universal Plugins Directory. Directory validator compatibility, portal/reviewer acceptance, search exposure, and promptless plugin-card Quick start behavior remain unverified and are not claimed here.
|
|
100
118
|
|
package/bin/codex-agent-view.mjs
CHANGED
|
@@ -32,6 +32,8 @@ import {
|
|
|
32
32
|
const PACKAGE_ROOT = resolve(fileURLToPath(new URL("../", import.meta.url)));
|
|
33
33
|
const PLUGIN_ID = "codex-agent-view@codex-agent-view";
|
|
34
34
|
const MARKETPLACE_NAME = "codex-agent-view";
|
|
35
|
+
const PLUGIN_BUNDLE_RELATIVE_PATH = join("plugins", "codex-agent-view");
|
|
36
|
+
const INSTALLED_MARKETPLACE_PLUGIN_SOURCE = "./plugins/codex-agent-view";
|
|
35
37
|
const BUNDLE_MARKER = ".codex-agent-view-owned.json";
|
|
36
38
|
const BUNDLE_MARKER_SCHEMA_VERSION = 1;
|
|
37
39
|
const PREPARE_LIVE_VIEW_WAIT_MS = 2_000;
|
|
@@ -50,8 +52,7 @@ const KNOWN_PRE_PROOF_MANAGED_VERSIONS = new Set([
|
|
|
50
52
|
]);
|
|
51
53
|
const CANONICAL_THREAD_ID_PATTERN =
|
|
52
54
|
/^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i;
|
|
53
|
-
const
|
|
54
|
-
".agents",
|
|
55
|
+
const PLUGIN_INSTALL_ENTRIES = [
|
|
55
56
|
".codex-plugin",
|
|
56
57
|
"assets",
|
|
57
58
|
"bin",
|
|
@@ -641,13 +642,11 @@ async function inspectInstalledBundleForLiveView() {
|
|
|
641
642
|
throw new LiveViewPreparationError("plugin_bundle_unowned");
|
|
642
643
|
}
|
|
643
644
|
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
);
|
|
647
|
-
if (manifest?.name !== MARKETPLACE_NAME || typeof manifest.version !== "string") {
|
|
645
|
+
const installedBundle = await inspectManagedBundleLayout(destination);
|
|
646
|
+
if (installedBundle === null) {
|
|
648
647
|
throw new LiveViewPreparationError("plugin_bundle_invalid");
|
|
649
648
|
}
|
|
650
|
-
if (
|
|
649
|
+
if (installedBundle.version !== (await packageVersion())) {
|
|
651
650
|
throw new LiveViewPreparationError("plugin_version_mismatch");
|
|
652
651
|
}
|
|
653
652
|
}
|
|
@@ -874,18 +873,46 @@ async function inspectPluginBundle(destination) {
|
|
|
874
873
|
}
|
|
875
874
|
|
|
876
875
|
const marker = await readJsonRegularFile(join(destination, BUNDLE_MARKER));
|
|
877
|
-
const manifest = await readJsonRegularFile(
|
|
878
|
-
join(destination, ".codex-plugin", "plugin.json"),
|
|
879
|
-
);
|
|
880
876
|
if (
|
|
881
877
|
marker?.schema_version !== BUNDLE_MARKER_SCHEMA_VERSION ||
|
|
882
878
|
marker?.package !== MARKETPLACE_NAME ||
|
|
883
|
-
marker?.plugin_id !== PLUGIN_ID
|
|
884
|
-
manifest?.name !== MARKETPLACE_NAME
|
|
879
|
+
marker?.plugin_id !== PLUGIN_ID
|
|
885
880
|
) {
|
|
886
881
|
return { kind: "unmanaged" };
|
|
887
882
|
}
|
|
888
|
-
|
|
883
|
+
const installedBundle = await inspectManagedBundleLayout(destination);
|
|
884
|
+
if (installedBundle === null) {
|
|
885
|
+
return { kind: "unmanaged" };
|
|
886
|
+
}
|
|
887
|
+
return {
|
|
888
|
+
kind: "managed",
|
|
889
|
+
layout: installedBundle.layout,
|
|
890
|
+
version: installedBundle.version,
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
async function inspectManagedBundleLayout(destination) {
|
|
895
|
+
const candidates = [
|
|
896
|
+
{
|
|
897
|
+
layout: "subdirectory",
|
|
898
|
+
path: join(destination, PLUGIN_BUNDLE_RELATIVE_PATH, ".codex-plugin", "plugin.json"),
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
layout: "legacy-root",
|
|
902
|
+
path: join(destination, ".codex-plugin", "plugin.json"),
|
|
903
|
+
},
|
|
904
|
+
];
|
|
905
|
+
const matches = [];
|
|
906
|
+
for (const candidate of candidates) {
|
|
907
|
+
const manifest = await readJsonRegularFile(candidate.path);
|
|
908
|
+
if (
|
|
909
|
+
manifest?.name === MARKETPLACE_NAME &&
|
|
910
|
+
typeof manifest.version === "string"
|
|
911
|
+
) {
|
|
912
|
+
matches.push({ layout: candidate.layout, version: manifest.version });
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
return matches.length === 1 ? matches[0] : null;
|
|
889
916
|
}
|
|
890
917
|
|
|
891
918
|
function legacyBearerProbeOptions(bundle) {
|
|
@@ -926,10 +953,31 @@ async function copyPluginBundle(destination) {
|
|
|
926
953
|
await rm(destination, { force: true, recursive: true });
|
|
927
954
|
}
|
|
928
955
|
await mkdir(destination, { mode: 0o700, recursive: true });
|
|
929
|
-
|
|
956
|
+
await cp(join(PACKAGE_ROOT, ".agents"), join(destination, ".agents"), {
|
|
957
|
+
errorOnExist: true,
|
|
958
|
+
force: false,
|
|
959
|
+
recursive: true,
|
|
960
|
+
});
|
|
961
|
+
const installedCatalogPath = join(destination, ".agents", "plugins", "marketplace.json");
|
|
962
|
+
const installedCatalog = JSON.parse(await readFile(installedCatalogPath, "utf8"));
|
|
963
|
+
const installedEntry = installedCatalog?.plugins?.find(
|
|
964
|
+
(entry) => entry?.name === MARKETPLACE_NAME,
|
|
965
|
+
);
|
|
966
|
+
if (installedEntry?.source?.source !== "local") {
|
|
967
|
+
throw new Error("the bundled marketplace catalog is invalid");
|
|
968
|
+
}
|
|
969
|
+
installedEntry.source.path = INSTALLED_MARKETPLACE_PLUGIN_SOURCE;
|
|
970
|
+
await writeFile(installedCatalogPath, `${JSON.stringify(installedCatalog, null, 2)}\n`, {
|
|
971
|
+
encoding: "utf8",
|
|
972
|
+
flag: "w",
|
|
973
|
+
mode: 0o600,
|
|
974
|
+
});
|
|
975
|
+
const pluginDestination = join(destination, PLUGIN_BUNDLE_RELATIVE_PATH);
|
|
976
|
+
await mkdir(pluginDestination, { mode: 0o700, recursive: true });
|
|
977
|
+
for (const entry of PLUGIN_INSTALL_ENTRIES) {
|
|
930
978
|
const source = join(PACKAGE_ROOT, entry);
|
|
931
979
|
if (!(await pathExists(source))) continue;
|
|
932
|
-
await cp(source, join(
|
|
980
|
+
await cp(source, join(pluginDestination, entry), {
|
|
933
981
|
errorOnExist: true,
|
|
934
982
|
force: false,
|
|
935
983
|
recursive: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-agent-view",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "A read-only Codex plugin for monitoring live tasks and subagents in your browser. Open each view with one lightweight @codex-agent-view invocation. Once open, live monitoring runs locally with no additional model calls.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/core/index.mjs",
|
package/public/app.js
CHANGED
|
@@ -125,10 +125,17 @@ const MESSAGES = Object.freeze({
|
|
|
125
125
|
emptyTitle: "No task activity has been received in this observation window.",
|
|
126
126
|
emptyCopy: "The local monitor is connected. This result alone does not mean that Codex has no active work or participating agents.",
|
|
127
127
|
emptyGuidanceTitle: "If work does not appear",
|
|
128
|
+
hookReviewTitle: "Check hook approval first",
|
|
129
|
+
hookReviewCopy: "No activity has reached this monitor. The hook may not be trusted or loaded yet, but this page cannot inspect Codex's saved hook-trust state.",
|
|
128
130
|
automaticTracking: "You do not need to enter or register task IDs. Activity from trusted hooks is added automatically.",
|
|
129
|
-
emptyStep1: "
|
|
130
|
-
emptyStep2: "
|
|
131
|
-
emptyStep3: "
|
|
131
|
+
emptyStep1: "In the Codex app, open Plugins > Codex Agent View, confirm that it is enabled, choose Review under Hooks, and then choose Trust all if those controls are available.",
|
|
132
|
+
emptyStep2: "If the app has no hook-review controls, open the interactive Codex CLI, run /hooks, inspect the current Codex Agent View command, and approve it.",
|
|
133
|
+
emptyStep3: "Fully quit and restart the official Codex app so it loads the current plugin and hook definition.",
|
|
134
|
+
emptyStep4: "After approval and restart, create a new task and start new work to verify delivery.",
|
|
135
|
+
viewerTaskHiddenTitle: "The viewer task is hidden from this page.",
|
|
136
|
+
viewerTaskHiddenCopy: "The only observed work item is the task that opened this view, so the visible list is empty.",
|
|
137
|
+
viewerTaskActionTitle: "Open the viewer from a separate task",
|
|
138
|
+
viewerTaskExclusion: "The task that opened this view is intentionally excluded. Open Codex Agent View from a separate lightweight viewer task, then start or continue the work you want to monitor in another task.",
|
|
132
139
|
observationBoundary: "Observation starts with the first trusted hook event. Earlier activity and activity missed while local collection was stopped cannot be replayed; restarting collection opens a new observation window.",
|
|
133
140
|
diagnosticsCount: "Validation information · {count}",
|
|
134
141
|
diagnosticOccurrences: "{count} occurrences",
|
|
@@ -280,10 +287,17 @@ const MESSAGES = Object.freeze({
|
|
|
280
287
|
emptyTitle: "이 관찰 화면에서 수신된 작업 활동이 없습니다.",
|
|
281
288
|
emptyCopy: "로컬 모니터 연결은 정상입니다. 이 결과만으로 Codex에 진행 중인 작업이나 참여 에이전트가 없다고 판단할 수 없습니다.",
|
|
282
289
|
emptyGuidanceTitle: "표시되지 않을 때 확인 순서",
|
|
290
|
+
hookReviewTitle: "먼저 Hook 승인 상태를 확인하세요",
|
|
291
|
+
hookReviewCopy: "아직 이 모니터에 도착한 활동이 없습니다. Hook이 신뢰되지 않았거나 아직 로드되지 않았을 수 있지만, 이 화면에서는 Codex에 저장된 Hook 신뢰 상태를 확인할 수 없습니다.",
|
|
283
292
|
automaticTracking: "작업 ID를 입력하거나 작업별로 등록할 필요가 없습니다. 신뢰한 hook의 작업 활동이 이 목록에 자동으로 추가됩니다.",
|
|
284
|
-
emptyStep1: "
|
|
285
|
-
emptyStep2: "
|
|
286
|
-
emptyStep3: "
|
|
293
|
+
emptyStep1: "Codex 앱에서 Plugins > Codex Agent View를 열어 활성화 상태를 확인하고, Hooks에서 '검토'를 누른 뒤 해당 버튼이 보이면 '모두 신뢰하기'를 선택합니다.",
|
|
294
|
+
emptyStep2: "앱에 Hook 검토 화면이 없다면 interactive Codex CLI에서 /hooks를 실행하고 현재 Codex Agent View 명령을 검토한 뒤 승인합니다.",
|
|
295
|
+
emptyStep3: "현재 플러그인과 Hook 정의를 다시 로드하도록 공식 Codex 앱을 완전히 종료한 뒤 재시작합니다.",
|
|
296
|
+
emptyStep4: "승인과 재시작을 마친 뒤 새 작업을 만들고 새로운 활동을 시작해 전달 여부를 확인합니다.",
|
|
297
|
+
viewerTaskHiddenTitle: "이 화면을 연 작업은 목록에서 숨겨집니다.",
|
|
298
|
+
viewerTaskHiddenCopy: "현재 관찰된 유일한 작업이 이 화면을 연 작업이므로 표시 목록이 비어 있습니다.",
|
|
299
|
+
viewerTaskActionTitle: "별도의 작업에서 보기 화면을 여세요",
|
|
300
|
+
viewerTaskExclusion: "이 화면을 연 작업은 의도적으로 제외됩니다. 별도의 가벼운 보기용 작업에서 Codex Agent View를 연 뒤, 다른 작업에서 관찰할 새 작업을 시작하거나 기존 작업을 계속하세요.",
|
|
287
301
|
observationBoundary: "관찰 화면은 첫 번째로 신뢰한 hook을 받은 시점부터 시작합니다. 그 전에 이미 지나간 활동과 로컬 상태 수집이 중단된 동안의 활동은 재생되지 않으며, 수집이 다시 시작되면 새 관찰 화면이 열립니다.",
|
|
288
302
|
diagnosticsCount: "검증 정보 · {count}건",
|
|
289
303
|
diagnosticOccurrences: "{count}건",
|
|
@@ -435,10 +449,17 @@ const MESSAGES = Object.freeze({
|
|
|
435
449
|
emptyTitle: "No se recibió actividad en esta ventana de observación.",
|
|
436
450
|
emptyCopy: "El monitor local está conectado. Este resultado no implica por sí solo que Codex no tenga trabajos o agentes activos.",
|
|
437
451
|
emptyGuidanceTitle: "Si el trabajo no aparece",
|
|
452
|
+
hookReviewTitle: "Comprueba primero la aprobación del hook",
|
|
453
|
+
hookReviewCopy: "Aún no llegó actividad a este monitor. Es posible que el hook todavía no sea confiable o no esté cargado, pero esta página no puede consultar el estado de confianza guardado por Codex.",
|
|
438
454
|
automaticTracking: "No es necesario introducir ni registrar IDs de tareas. La actividad de hooks confiables se añade automáticamente.",
|
|
439
|
-
emptyStep1: "
|
|
440
|
-
emptyStep2: "
|
|
441
|
-
emptyStep3: "
|
|
455
|
+
emptyStep1: "En la aplicación Codex, abre Plugins > Codex Agent View, confirma que esté activado, elige Revisar en Hooks y después Confiar en todos si aparecen esos controles.",
|
|
456
|
+
emptyStep2: "Si la aplicación no tiene controles para revisar hooks, abre la CLI interactiva de Codex, ejecuta /hooks, inspecciona el comando actual de Codex Agent View y apruébalo.",
|
|
457
|
+
emptyStep3: "Cierra por completo y reinicia la aplicación oficial de Codex para que cargue el plugin y la definición de hook actuales.",
|
|
458
|
+
emptyStep4: "Después de aprobar y reiniciar, crea una tarea nueva e inicia trabajo nuevo para verificar la entrega.",
|
|
459
|
+
viewerTaskHiddenTitle: "La tarea que abrió esta vista está oculta.",
|
|
460
|
+
viewerTaskHiddenCopy: "El único trabajo observado es la tarea que abrió esta vista, por eso la lista visible está vacía.",
|
|
461
|
+
viewerTaskActionTitle: "Abre el visor desde otra tarea",
|
|
462
|
+
viewerTaskExclusion: "La tarea que abrió esta vista se excluye intencionalmente. Abre Codex Agent View desde otra tarea ligera de visualización y después inicia o continúa el trabajo que quieras observar en una tarea diferente.",
|
|
442
463
|
observationBoundary: "La observación comienza con el primer evento de un hook autorizado. La actividad anterior o perdida mientras la recopilación local estuvo detenida no se puede reproducir; al reiniciarla se abre una ventana nueva.",
|
|
443
464
|
diagnosticsCount: "Información de validación · {count}",
|
|
444
465
|
diagnosticOccurrences: "{count} apariciones",
|
|
@@ -1713,12 +1734,26 @@ function setEmptyObservationMessage() {
|
|
|
1713
1734
|
elements.stateMessage.className = "state-message state-empty state-empty-observation";
|
|
1714
1735
|
elements.stateMessage.replaceChildren();
|
|
1715
1736
|
|
|
1737
|
+
const rawSessions = Array.isArray(viewState.sessions) ? viewState.sessions : [];
|
|
1738
|
+
const hasOnlyExcludedViewerTask =
|
|
1739
|
+
rawSessions.length > 0 &&
|
|
1740
|
+
observableSessions().length === 0 &&
|
|
1741
|
+
CANONICAL_SESSION_ID_PATTERN.test(excludedSessionId) &&
|
|
1742
|
+
rawSessions.some((session) => session.sessionId === excludedSessionId);
|
|
1743
|
+
const noHookEventsObserved =
|
|
1744
|
+
viewState.diagnostics.length === 0 &&
|
|
1745
|
+
rawSessions.length === 0 &&
|
|
1746
|
+
(!Number.isFinite(viewState.updatedAtMs) || viewState.updatedAtMs <= 0);
|
|
1747
|
+
|
|
1716
1748
|
const heading = document.createElement("strong");
|
|
1717
1749
|
const copy = document.createElement("span");
|
|
1718
1750
|
|
|
1719
1751
|
if (viewState.diagnostics.length) {
|
|
1720
1752
|
heading.textContent = t("emptyWithDiagnosticsTitle");
|
|
1721
1753
|
copy.textContent = t("emptyWithDiagnosticsCopy", { count: viewState.diagnostics.length });
|
|
1754
|
+
} else if (hasOnlyExcludedViewerTask) {
|
|
1755
|
+
heading.textContent = t("viewerTaskHiddenTitle");
|
|
1756
|
+
copy.textContent = t("viewerTaskHiddenCopy");
|
|
1722
1757
|
} else {
|
|
1723
1758
|
heading.textContent = t("emptyTitle");
|
|
1724
1759
|
copy.textContent = t("emptyCopy");
|
|
@@ -1734,18 +1769,45 @@ function setEmptyObservationMessage() {
|
|
|
1734
1769
|
automaticTracking.className = "automatic-tracking";
|
|
1735
1770
|
automaticTracking.textContent = t("automaticTracking");
|
|
1736
1771
|
|
|
1737
|
-
const steps = document.createElement("ol");
|
|
1738
|
-
for (const step of [t("emptyStep1"), t("emptyStep2"), t("emptyStep3")]) {
|
|
1739
|
-
const item = document.createElement("li");
|
|
1740
|
-
item.textContent = step;
|
|
1741
|
-
steps.append(item);
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
1772
|
const boundary = document.createElement("p");
|
|
1745
1773
|
boundary.className = "observation-boundary";
|
|
1746
1774
|
boundary.textContent = t("observationBoundary");
|
|
1747
1775
|
|
|
1748
|
-
guidance.append(guidanceTitle
|
|
1776
|
+
guidance.append(guidanceTitle);
|
|
1777
|
+
if (hasOnlyExcludedViewerTask) {
|
|
1778
|
+
const viewerTaskCallout = document.createElement("section");
|
|
1779
|
+
viewerTaskCallout.className = "viewer-task-callout";
|
|
1780
|
+
const viewerTaskTitle = document.createElement("h4");
|
|
1781
|
+
viewerTaskTitle.textContent = t("viewerTaskActionTitle");
|
|
1782
|
+
const viewerTaskCopy = document.createElement("p");
|
|
1783
|
+
viewerTaskCopy.textContent = t("viewerTaskExclusion");
|
|
1784
|
+
viewerTaskCallout.append(viewerTaskTitle, viewerTaskCopy);
|
|
1785
|
+
guidance.append(viewerTaskCallout);
|
|
1786
|
+
} else if (noHookEventsObserved) {
|
|
1787
|
+
const hookReview = document.createElement("section");
|
|
1788
|
+
hookReview.className = "hook-review-callout";
|
|
1789
|
+
const hookReviewTitle = document.createElement("h4");
|
|
1790
|
+
hookReviewTitle.textContent = t("hookReviewTitle");
|
|
1791
|
+
const hookReviewCopy = document.createElement("p");
|
|
1792
|
+
hookReviewCopy.textContent = t("hookReviewCopy");
|
|
1793
|
+
hookReview.append(hookReviewTitle, hookReviewCopy);
|
|
1794
|
+
|
|
1795
|
+
const steps = document.createElement("ol");
|
|
1796
|
+
for (const step of [
|
|
1797
|
+
t("emptyStep1"),
|
|
1798
|
+
t("emptyStep2"),
|
|
1799
|
+
t("emptyStep3"),
|
|
1800
|
+
t("emptyStep4"),
|
|
1801
|
+
]) {
|
|
1802
|
+
const item = document.createElement("li");
|
|
1803
|
+
item.textContent = step;
|
|
1804
|
+
steps.append(item);
|
|
1805
|
+
}
|
|
1806
|
+
guidance.append(hookReview, automaticTracking, steps);
|
|
1807
|
+
} else {
|
|
1808
|
+
guidance.append(automaticTracking);
|
|
1809
|
+
}
|
|
1810
|
+
guidance.append(boundary);
|
|
1749
1811
|
|
|
1750
1812
|
if (viewState.diagnostics.length) {
|
|
1751
1813
|
const diagnostics = document.createElement("div");
|
package/public/styles.css
CHANGED
|
@@ -482,6 +482,29 @@ h1 {
|
|
|
482
482
|
font-size: var(--text-sm);
|
|
483
483
|
}
|
|
484
484
|
|
|
485
|
+
.hook-review-callout,
|
|
486
|
+
.viewer-task-callout {
|
|
487
|
+
margin-bottom: var(--space-4);
|
|
488
|
+
padding: var(--space-4);
|
|
489
|
+
background: color-mix(in srgb, var(--accent) 9%, var(--surface-raised));
|
|
490
|
+
border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--border-default));
|
|
491
|
+
border-left: 0.3rem solid var(--accent);
|
|
492
|
+
border-radius: var(--radius-sm);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
.hook-review-callout h4,
|
|
496
|
+
.viewer-task-callout h4 {
|
|
497
|
+
margin-bottom: var(--space-2);
|
|
498
|
+
font-size: var(--text-md);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.hook-review-callout p,
|
|
502
|
+
.viewer-task-callout p {
|
|
503
|
+
margin: 0;
|
|
504
|
+
color: var(--text-secondary);
|
|
505
|
+
font-size: var(--text-sm);
|
|
506
|
+
}
|
|
507
|
+
|
|
485
508
|
.automatic-tracking {
|
|
486
509
|
margin-bottom: var(--space-3);
|
|
487
510
|
color: var(--text-secondary);
|