cli-jaw 2.17.44 → 2.17.45
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/README.ja.md +5 -7
- package/README.ko.md +5 -7
- package/README.md +19 -7
- package/README.zh-CN.md +5 -7
- package/dist/bin/commands/dispatch.js +93 -18
- package/dist/bin/commands/dispatch.js.map +1 -1
- package/dist/bin/commands/doctor.js +0 -70
- package/dist/bin/commands/doctor.js.map +1 -1
- package/dist/bin/commands/provider.js +16 -28
- package/dist/bin/commands/provider.js.map +1 -1
- package/dist/bin/commands/slack.js +65 -2
- package/dist/bin/commands/slack.js.map +1 -1
- package/dist/bin/commands/tui/slash-command-runner.js +1 -1
- package/dist/bin/commands/tui/slash-command-runner.js.map +1 -1
- package/dist/bin/commands/tui/types.js +0 -4
- package/dist/bin/commands/tui/types.js.map +1 -1
- package/dist/scripts/fresh-install-smoke.js +1 -1
- package/dist/scripts/fresh-install-smoke.js.map +1 -1
- package/dist/server.js +5 -3
- package/dist/server.js.map +1 -1
- package/dist/src/agent/args.js +1 -176
- package/dist/src/agent/args.js.map +1 -1
- package/dist/src/agent/claude-runtime-pool.js +11 -7
- package/dist/src/agent/claude-runtime-pool.js.map +1 -1
- package/dist/src/agent/cli-helpers.js +1 -3
- package/dist/src/agent/cli-helpers.js.map +1 -1
- package/dist/src/agent/error-classifier.js +1 -1
- package/dist/src/agent/error-classifier.js.map +1 -1
- package/dist/src/agent/error-cooldown.js +1 -3
- package/dist/src/agent/error-cooldown.js.map +1 -1
- package/dist/src/agent/events/claude.js +4 -56
- package/dist/src/agent/events/claude.js.map +1 -1
- package/dist/src/agent/events/helpers.js +3 -5
- package/dist/src/agent/events/helpers.js.map +1 -1
- package/dist/src/agent/events/index.js +12 -18
- package/dist/src/agent/events/index.js.map +1 -1
- package/dist/src/agent/kiro-runtime.js +3 -16
- package/dist/src/agent/kiro-runtime.js.map +1 -1
- package/dist/src/agent/lifecycle-handler.js +17 -12
- package/dist/src/agent/lifecycle-handler.js.map +1 -1
- package/dist/src/agent/native-runtime-run.js +7 -2
- package/dist/src/agent/native-runtime-run.js.map +1 -1
- package/dist/src/agent/prompt-context.js +4 -5
- package/dist/src/agent/prompt-context.js.map +1 -1
- package/dist/src/agent/resume-classifier.js +0 -5
- package/dist/src/agent/resume-classifier.js.map +1 -1
- package/dist/src/agent/runtime/acp/cursor-session.js +21 -3
- package/dist/src/agent/runtime/acp/cursor-session.js.map +1 -1
- package/dist/src/agent/runtime-pool.js +127 -51
- package/dist/src/agent/runtime-pool.js.map +1 -1
- package/dist/src/agent/session-persistence.js +1 -6
- package/dist/src/agent/session-persistence.js.map +1 -1
- package/dist/src/agent/spawn/resume.js +3 -3
- package/dist/src/agent/spawn/resume.js.map +1 -1
- package/dist/src/agent/spawn.js +27 -96
- package/dist/src/agent/spawn.js.map +1 -1
- package/dist/src/cli/claude-models.js +1 -1
- package/dist/src/cli/claude-models.js.map +1 -1
- package/dist/src/cli/cli-status-worker.js +1 -8
- package/dist/src/cli/cli-status-worker.js.map +1 -1
- package/dist/src/cli/compact.js +2 -6
- package/dist/src/cli/compact.js.map +1 -1
- package/dist/src/cli/employee-handler.js +4 -0
- package/dist/src/cli/employee-handler.js.map +1 -1
- package/dist/src/cli/handlers-completions.js +1 -1
- package/dist/src/cli/handlers-completions.js.map +1 -1
- package/dist/src/cli/handlers-runtime.js +18 -8
- package/dist/src/cli/handlers-runtime.js.map +1 -1
- package/dist/src/cli/handlers.js +3 -31
- package/dist/src/cli/handlers.js.map +1 -1
- package/dist/src/cli/opencodex-models.js +0 -5
- package/dist/src/cli/opencodex-models.js.map +1 -1
- package/dist/src/cli/readiness.js +1 -20
- package/dist/src/cli/readiness.js.map +1 -1
- package/dist/src/cli/registry-live.js +1 -51
- package/dist/src/cli/registry-live.js.map +1 -1
- package/dist/src/cli/registry.js +0 -64
- package/dist/src/cli/registry.js.map +1 -1
- package/dist/src/core/chat-sessions.js +3 -2
- package/dist/src/core/chat-sessions.js.map +1 -1
- package/dist/src/core/cli-detection.js +2 -178
- package/dist/src/core/cli-detection.js.map +1 -1
- package/dist/src/core/compact.js +2 -4
- package/dist/src/core/compact.js.map +1 -1
- package/dist/src/core/config.js +5 -4
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/runtime-settings.js +5 -20
- package/dist/src/core/runtime-settings.js.map +1 -1
- package/dist/src/core/session-ops.js +4 -6
- package/dist/src/core/session-ops.js.map +1 -1
- package/dist/src/core/windows-launch-spec.js +1 -1
- package/dist/src/http/full-access.js +42 -0
- package/dist/src/http/full-access.js.map +1 -0
- package/dist/src/manager/proxy.js +1 -0
- package/dist/src/manager/proxy.js.map +1 -1
- package/dist/src/messaging/send.js +30 -8
- package/dist/src/messaging/send.js.map +1 -1
- package/dist/src/orchestrator/dispatch-admission.js +424 -0
- package/dist/src/orchestrator/dispatch-admission.js.map +1 -0
- package/dist/src/orchestrator/distribute.js +63 -21
- package/dist/src/orchestrator/distribute.js.map +1 -1
- package/dist/src/orchestrator/gateway.js +6 -4
- package/dist/src/orchestrator/gateway.js.map +1 -1
- package/dist/src/orchestrator/worker-registry.js +8 -1
- package/dist/src/orchestrator/worker-registry.js.map +1 -1
- package/dist/src/prompt/builder.js +40 -16
- package/dist/src/prompt/builder.js.map +1 -1
- package/dist/src/prompt/templates/employee.md +4 -4
- package/dist/src/routes/messaging.js +34 -18
- package/dist/src/routes/messaging.js.map +1 -1
- package/dist/src/routes/orchestrate.js +139 -64
- package/dist/src/routes/orchestrate.js.map +1 -1
- package/dist/src/routes/settings.js +1 -30
- package/dist/src/routes/settings.js.map +1 -1
- package/dist/src/routes/slack-tools.js +6 -4
- package/dist/src/routes/slack-tools.js.map +1 -1
- package/dist/src/security/path-guards.js +15 -1
- package/dist/src/security/path-guards.js.map +1 -1
- package/dist/src/slack/search-quote.js +9 -5
- package/dist/src/slack/search-quote.js.map +1 -1
- package/dist/src/slack/send-handler.js +1 -25
- package/dist/src/slack/send-handler.js.map +1 -1
- package/dist/src/slack/slack-file.js +105 -53
- package/dist/src/slack/slack-file.js.map +1 -1
- package/dist/src/slack/tool-access.js +10 -2
- package/dist/src/slack/tool-access.js.map +1 -1
- package/dist/src/slack/tool-capabilities.js +16 -8
- package/dist/src/slack/tool-capabilities.js.map +1 -1
- package/dist/src/types/cli-engine.js +26 -3
- package/dist/src/types/cli-engine.js.map +1 -1
- package/dist/src/types/cli-events.js +1 -1
- package/dist/src/types/cli-events.js.map +1 -1
- package/dist/src/workflows/employee-boundary.js +9 -5
- package/dist/src/workflows/employee-boundary.js.map +1 -1
- package/dist/src/workflows/scope-sandbox.js +5 -2
- package/dist/src/workflows/scope-sandbox.js.map +1 -1
- package/package.json +2 -6
- package/public/dist/.vite/manifest.json +115 -115
- package/public/dist/assets/Agent-CKX93LQ8.js +1 -0
- package/public/dist/assets/Employees-BuFw6-fT.js +1 -0
- package/public/dist/assets/Heartbeat-BmkZshEU.js +1 -0
- package/public/dist/assets/Memory-DsK_yOCW.js +1 -0
- package/public/dist/assets/ModelProvider-L_hW6YWJ.js +1 -0
- package/public/dist/assets/agent-meta-CkRJlOmN.js +1 -0
- package/public/dist/assets/{app-9OQNfmqw.js → app-B_JTnXIY.js} +4 -4
- package/public/dist/assets/{bgtask-badge-BvxHqMGi.js → bgtask-badge-BLdI7Ara.js} +1 -1
- package/public/dist/assets/bgtask-badge-DOhTsE9l.js +1 -0
- package/public/dist/assets/cli-engine-NdU0lzs_.js +1 -0
- package/public/dist/assets/constants-DmRtjRj3.js +1 -0
- package/public/dist/assets/{employees-CkUqN4oh.js → employees-DGoVBWQd.js} +1 -1
- package/public/dist/assets/iframe-renderer-Dw5vTqFX.js +1 -0
- package/public/dist/assets/{iframe-renderer-C2gchtOj.js → iframe-renderer-mBjdW5ZV.js} +2 -2
- package/public/dist/assets/{manager-rb5X-4DJ.js → manager-iX7KosWI.js} +1 -1
- package/public/dist/assets/memory-DuHc2no-.js +1 -0
- package/public/dist/assets/{memory-BiWzpoBq.js → memory-Hq9y-GQB.js} +1 -1
- package/public/dist/assets/message-history-DT0VaJRd.js +1 -0
- package/public/dist/assets/{message-history-CuFefS02.js → message-history-H7G4apTo.js} +1 -1
- package/public/dist/assets/{provider-icons-Det0fC-4.js → provider-icons-Bge6teOj.js} +1 -1
- package/public/dist/assets/{render-DUGqq9Mu.js → render-OT0puqo3.js} +1 -1
- package/public/dist/assets/settings-BW8q_Rnq.js +1 -0
- package/public/dist/assets/{settings-DQ1fLygB.js → settings-DjCtFSpd.js} +3 -3
- package/public/dist/assets/{settings-BqUHavbH.js → settings-KIPNUOIV.js} +1 -1
- package/public/dist/assets/settings-core-CVO3_bn9.js +1 -0
- package/public/dist/assets/settings-core-DiStY7KC.js +2 -0
- package/public/dist/assets/{settings-embedding-BAKFrVLV.js → settings-embedding-DIqST-91.js} +1 -1
- package/public/dist/assets/{sidebar-CvGbp9x5.js → sidebar-DiS6dGEP.js} +3 -3
- package/public/dist/assets/{skills-abLMqY5_.js → skills-D_mbeyb3.js} +1 -1
- package/public/dist/assets/skills-NzM-geDj.js +1 -0
- package/public/dist/assets/slash-commands-DUk5bLQ1.js +1 -0
- package/public/dist/assets/{slash-commands-D8o9pqOS.js → slash-commands-PWDX9hXL.js} +1 -1
- package/public/dist/assets/{trace-drawer-C6RvkUAd.js → trace-drawer-DSn3xg8f.js} +1 -1
- package/public/dist/assets/{ui-Bxapl_Eu.js → ui-Dzebjyzl.js} +1 -1
- package/public/dist/assets/ui-TcZtZTFR.js +1 -0
- package/public/dist/index.html +1 -3
- package/public/dist/manager/index.html +1 -1
- package/public/dist/settings/index.html +1 -1
- package/public/index.html +0 -2
- package/public/js/constants.ts +1 -46
- package/public/js/features/employees.ts +1 -1
- package/public/js/features/retired-runtime-option.ts +2 -2
- package/public/js/features/settings-channel.ts +4 -2
- package/public/js/features/settings-cli-status-render.ts +2 -2
- package/public/js/features/settings-cli-status.ts +0 -2
- package/public/js/provider-icons.ts +1 -3
- package/public/manager/src/settings/pages/Heartbeat.tsx +2 -2
- package/public/manager/src/settings/pages/Memory.tsx +2 -2
- package/public/manager/src/settings/pages/ModelProvider.tsx +7 -4
- package/public/manager/src/settings/pages/components/agent/FlushAgentSection.tsx +2 -2
- package/public/manager/src/settings/pages/components/agent/RuntimeEmployeeRow.tsx +2 -2
- package/public/manager/src/settings/pages/components/agent/RuntimeHeader.tsx +2 -2
- package/public/manager/src/settings/pages/components/agent/agent-meta.ts +4 -35
- package/public/manager/src/settings/pages/components/employees-helpers.ts +0 -2
- package/public/manager/src/settings/pages/components/heartbeat-helpers.ts +0 -2
- package/scripts/bundle-sidecar.sh +0 -24
- package/scripts/check-electron-sidecar-no-jwc.cjs +12 -4
- package/scripts/fresh-install-smoke.ts +1 -1
- package/scripts/install.sh +0 -5
- package/scripts/retired-runtime-package-smoke.mjs +2 -12
- package/scripts/verify-fresh-install.sh +0 -14
- package/dist/src/agent/claude-e-runtime.js +0 -44
- package/dist/src/agent/claude-e-runtime.js.map +0 -1
- package/public/dist/assets/Agent-CNad_A6t.js +0 -1
- package/public/dist/assets/Employees-B6uviPeN.js +0 -1
- package/public/dist/assets/Heartbeat-C3S3d8xW.js +0 -1
- package/public/dist/assets/Memory-BgeIbQSr.js +0 -1
- package/public/dist/assets/ModelProvider-AnxBVYws.js +0 -1
- package/public/dist/assets/agent-meta-BWHASq1a.js +0 -1
- package/public/dist/assets/bgtask-badge-DeSZJGNN.js +0 -1
- package/public/dist/assets/cli-engine-Bw0QTAVX.js +0 -1
- package/public/dist/assets/constants-D8XAqfHk.js +0 -1
- package/public/dist/assets/iframe-renderer-DfvACXIn.js +0 -1
- package/public/dist/assets/memory-Ckp1Eq5a.js +0 -1
- package/public/dist/assets/message-history-Bv0l_t7O.js +0 -1
- package/public/dist/assets/settings-C81Kf9uX.js +0 -1
- package/public/dist/assets/settings-core-CzdXfoOK.js +0 -2
- package/public/dist/assets/settings-core-DO_5M7Lv.js +0 -1
- package/public/dist/assets/skills-DFpPmMUR.js +0 -1
- package/public/dist/assets/slash-commands-BU58xYih.js +0 -1
- package/public/dist/assets/ui-CUB4iwz3.js +0 -1
|
@@ -26,7 +26,7 @@ import slackSvg from '../assets/providers/slack.svg?raw';
|
|
|
26
26
|
import telegramSvg from '../assets/providers/telegram.svg?raw';
|
|
27
27
|
import opencodeSvg from '../assets/providers/opencode.svg?raw';
|
|
28
28
|
|
|
29
|
-
export type ProviderSlug = '
|
|
29
|
+
export type ProviderSlug = 'claude' | 'openai' | 'gemini' | 'antigravity' | 'grok' | 'copilot' | 'cursor' | 'kiro-code' | 'codex' | 'codex-app' | 'opencode' | 'discord' | 'telegram' | 'slack';
|
|
30
30
|
|
|
31
31
|
interface ProviderIcon {
|
|
32
32
|
color: string;
|
|
@@ -37,7 +37,6 @@ interface ProviderIcon {
|
|
|
37
37
|
const openaiColorSvg = openaiSvg.replace('fill="currentColor"', 'fill="#10A37F"');
|
|
38
38
|
|
|
39
39
|
const PROVIDER_ICONS: Record<ProviderSlug, ProviderIcon> = {
|
|
40
|
-
'ai-e': { color: openaiColorSvg, mono: openaiSvg, label: 'AI-E' },
|
|
41
40
|
claude: { color: claudeSvg, mono: claudeMonoSvg, label: 'Claude' },
|
|
42
41
|
openai: { color: openaiColorSvg, mono: openaiSvg, label: 'OpenAI' },
|
|
43
42
|
gemini: { color: geminiSvg, mono: geminiMonoSvg, label: 'Gemini' },
|
|
@@ -67,7 +66,6 @@ const PROVIDER_LABEL_ALIASES: Record<string, string> = {
|
|
|
67
66
|
|
|
68
67
|
function resolveProviderSlug(slug: string): ProviderSlug | null {
|
|
69
68
|
const normalized = slug.toLowerCase().replace(/[-_\s]/g, '');
|
|
70
|
-
if (normalized === 'aie') return 'ai-e';
|
|
71
69
|
if (normalized === 'claude' || normalized.startsWith('claude')) return 'claude';
|
|
72
70
|
if (normalized === 'gemini' || normalized.startsWith('gemini')) return 'gemini';
|
|
73
71
|
if (normalized === 'antigravity' || normalized === 'agy' || normalized === 'googleantigravity') return 'antigravity';
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
validateHHMM,
|
|
36
36
|
validateInterval,
|
|
37
37
|
} from './components/heartbeat-helpers';
|
|
38
|
-
import { metaFor, selectableRuntimeOptions, isRetiredCliSelection } from './components/agent/agent-meta';
|
|
38
|
+
import { metaFor, selectableRuntimeOptions, isRetiredCliSelection, retiredRuntimeLabel } from './components/agent/agent-meta';
|
|
39
39
|
|
|
40
40
|
// Re-export helpers (and types) that tests import from this module.
|
|
41
41
|
export {
|
|
@@ -240,7 +240,7 @@ export default function Heartbeat({ port, client, dirty, registerSave }: Setting
|
|
|
240
240
|
id="hb-target"
|
|
241
241
|
label="Target"
|
|
242
242
|
value={hbTarget}
|
|
243
|
-
missingValueLabel={isRetiredCliSelection(hbTarget) ?
|
|
243
|
+
missingValueLabel={isRetiredCliSelection(hbTarget) ? retiredRuntimeLabel(hbTarget) : undefined}
|
|
244
244
|
error={isRetiredCliSelection(hbTarget) ? 'The saved target runtime is retired. Choose an available target.' : null}
|
|
245
245
|
options={targetOptions}
|
|
246
246
|
onChange={(next) => {
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
type MemoryBlock,
|
|
36
36
|
type MemoryEntry,
|
|
37
37
|
} from './components/memory-helpers';
|
|
38
|
-
import { metaFor, selectableRuntimeOptions, isRetiredCliSelection } from './components/agent/agent-meta';
|
|
38
|
+
import { metaFor, selectableRuntimeOptions, isRetiredCliSelection, retiredRuntimeLabel } from './components/agent/agent-meta';
|
|
39
39
|
|
|
40
40
|
// Re-export pure helpers for unit tests (Heartbeat pattern).
|
|
41
41
|
export {
|
|
@@ -274,7 +274,7 @@ export default function Memory({ port, client, dirty, registerSave }: SettingsPa
|
|
|
274
274
|
id="memory-cli"
|
|
275
275
|
label="Flush CLI"
|
|
276
276
|
value={cli}
|
|
277
|
-
missingValueLabel={isRetiredCliSelection(cli) ?
|
|
277
|
+
missingValueLabel={isRetiredCliSelection(cli) ? retiredRuntimeLabel(cli) : undefined}
|
|
278
278
|
error={isRetiredCliSelection(cli) ? 'The saved runtime is retired. Choose an available runtime.' : null}
|
|
279
279
|
options={cliOptions}
|
|
280
280
|
onChange={(next) => {
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
type SnapshotState,
|
|
15
15
|
} from './page-shell';
|
|
16
16
|
import { PerCliRow, type PiRegistration } from './components/PerCliRow';
|
|
17
|
-
import { metaFor, normalizeCliMetaRegistry, selectableRuntimeOptions, isRetiredCliSelection } from './components/agent/agent-meta';
|
|
17
|
+
import { metaFor, normalizeCliMetaRegistry, selectableRuntimeOptions, isRetiredCliSelection, retiredRuntimeLabel } from './components/agent/agent-meta';
|
|
18
18
|
import type { CliMeta, PerCliEntry } from './components/agent/agent-meta';
|
|
19
19
|
import type { PiSettingsView } from './components/pi-profile';
|
|
20
20
|
import { expandPatch } from './path-utils';
|
|
@@ -40,8 +40,6 @@ export function orderModelCliKeys(keys: string[]): string[] {
|
|
|
40
40
|
return selectableRuntimeOptions(keys).sort((a, b) => {
|
|
41
41
|
if (a === 'pi') return -1;
|
|
42
42
|
if (b === 'pi') return 1;
|
|
43
|
-
if (a === 'ai-e') return b === 'pi' ? 1 : -1;
|
|
44
|
-
if (b === 'ai-e') return a === 'pi' ? -1 : 1;
|
|
45
43
|
return 0;
|
|
46
44
|
});
|
|
47
45
|
}
|
|
@@ -331,7 +329,12 @@ export default function ModelProvider({ port, client, dirty, registerSave }: Set
|
|
|
331
329
|
<ChipListField
|
|
332
330
|
id="model-fallbackOrder"
|
|
333
331
|
label="Fallback order"
|
|
334
|
-
error={
|
|
332
|
+
error={(() => {
|
|
333
|
+
const retired = fallback.find(isRetiredCliSelection);
|
|
334
|
+
if (!retired) return null;
|
|
335
|
+
const name = retiredRuntimeLabel(retired).replace(' (retired)', '');
|
|
336
|
+
return `A saved ${name} fallback is retired. Remove it before changing this order.`;
|
|
337
|
+
})()}
|
|
335
338
|
disabled={saving || resetting}
|
|
336
339
|
value={fallback}
|
|
337
340
|
onChange={(next) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SelectField } from '../../../fields';
|
|
2
2
|
import { SettingsSection } from '../../page-shell';
|
|
3
|
-
import { metaFor, selectableRuntimeOptions, isRetiredCliSelection, type CliMeta } from './agent-meta';
|
|
3
|
+
import { metaFor, selectableRuntimeOptions, isRetiredCliSelection, retiredRuntimeLabel, type CliMeta } from './agent-meta';
|
|
4
4
|
|
|
5
5
|
type FlushAgentSectionProps = {
|
|
6
6
|
activeCli: string;
|
|
@@ -46,7 +46,7 @@ export function FlushAgentSection({
|
|
|
46
46
|
id="agent-flush-cli"
|
|
47
47
|
label="Flush CLI"
|
|
48
48
|
value={flushCli}
|
|
49
|
-
missingValueLabel={isRetiredCliSelection(flushCli) ?
|
|
49
|
+
missingValueLabel={isRetiredCliSelection(flushCli) ? retiredRuntimeLabel(flushCli) : undefined}
|
|
50
50
|
error={isRetiredCliSelection(effectiveCli) ? 'The saved flush runtime is retired. Choose an available runtime.' : null}
|
|
51
51
|
options={[
|
|
52
52
|
{ value: '', label: '(active CLI)' },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SelectField, TextField } from '../../../fields';
|
|
2
|
-
import { metaFor, optionList, selectableRuntimeOptions, isRetiredCliSelection, type CliMeta } from './agent-meta';
|
|
2
|
+
import { metaFor, optionList, selectableRuntimeOptions, isRetiredCliSelection, retiredRuntimeLabel, type CliMeta } from './agent-meta';
|
|
3
3
|
import {
|
|
4
4
|
isStaticEmployee,
|
|
5
5
|
runtimeEmployeeError,
|
|
@@ -49,7 +49,7 @@ export function RuntimeEmployeeRow({
|
|
|
49
49
|
id={`runtime-employee-${employee.id}-cli`}
|
|
50
50
|
label="CLI"
|
|
51
51
|
value={employee.cli}
|
|
52
|
-
missingValueLabel={
|
|
52
|
+
missingValueLabel={isRetiredCliSelection(employee.cli) ? retiredRuntimeLabel(employee.cli) : undefined}
|
|
53
53
|
error={retired ? 'This saved runtime cannot execute. Choose an available runtime.' : null}
|
|
54
54
|
disabled={locked}
|
|
55
55
|
options={cliChoices.map((value) => ({ value, label: metaFor(value, cliMeta).label || value }))}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SelectField, TextField } from '../../../fields';
|
|
2
2
|
import { SettingsSection } from '../../page-shell';
|
|
3
|
-
import { metaFor, orderRuntimeCliOptions, PRIMARY_CLIS, isRetiredCliSelection, type CliMeta } from './agent-meta';
|
|
3
|
+
import { metaFor, orderRuntimeCliOptions, PRIMARY_CLIS, isRetiredCliSelection, retiredRuntimeLabel, type CliMeta } from './agent-meta';
|
|
4
4
|
|
|
5
5
|
type RuntimeHeaderProps = {
|
|
6
6
|
cli: string;
|
|
@@ -53,7 +53,7 @@ export function RuntimeHeader({
|
|
|
53
53
|
id="agent-cli"
|
|
54
54
|
label="Active CLI"
|
|
55
55
|
value={cli}
|
|
56
|
-
missingValueLabel={
|
|
56
|
+
missingValueLabel={isRetiredCliSelection(cli) ? retiredRuntimeLabel(cli) : undefined}
|
|
57
57
|
error={retired ? 'This runtime is retired. Select an available runtime to continue.' : null}
|
|
58
58
|
options={orderedCliOptions.map((value) => ({ value, label: metaFor(value, cliMeta).label || value }))}
|
|
59
59
|
collapsedAfter={orderedPrimaryCliCount}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isRetiredCliSelection } from '../../../../../../../src/types/cli-engine';
|
|
2
|
-
export { isRetiredCliSelection };
|
|
1
|
+
import { isRetiredCliSelection, retiredRuntimeLabel } from '../../../../../../../src/types/cli-engine';
|
|
2
|
+
export { isRetiredCliSelection, retiredRuntimeLabel };
|
|
3
3
|
import type { RuntimeTransport } from '../../../../../../../src/shared/runtime-contract';
|
|
4
4
|
|
|
5
5
|
export type CliMeta = {
|
|
@@ -49,7 +49,7 @@ export type ActiveOverride = {
|
|
|
49
49
|
|
|
50
50
|
const CODEX_MODELS: ReadonlyArray<string> = ['gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.3-codex-spark', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna'];
|
|
51
51
|
|
|
52
|
-
export const PRIMARY_CLIS: ReadonlyArray<string> = ['pi', 'claude', '
|
|
52
|
+
export const PRIMARY_CLIS: ReadonlyArray<string> = ['pi', 'claude', 'agy', 'codex', 'cursor', 'kiro-code', 'gemini'];
|
|
53
53
|
|
|
54
54
|
export const CLI_META: Record<string, CliMeta> = {
|
|
55
55
|
agy: {
|
|
@@ -75,29 +75,6 @@ export const CLI_META: Record<string, CliMeta> = {
|
|
|
75
75
|
efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
76
76
|
effortNote: 'Pi runs through --mode rpc. grok-composer-2.5-fast is the verified default; bare grok-composer-2.5 currently has no team access.',
|
|
77
77
|
},
|
|
78
|
-
'ai-e': {
|
|
79
|
-
label: 'AI-E',
|
|
80
|
-
defaultProvider: 'claude',
|
|
81
|
-
providers: ['claude', 'codex', 'gemini', 'grok', 'copilot', 'kiro'],
|
|
82
|
-
models: ['opus', 'sonnet', 'haiku', ...CODEX_MODELS, 'gemini-3-flash-preview', 'grok-build', 'grok-composer-2.5-fast', 'gpt-5-mini'],
|
|
83
|
-
efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
84
|
-
modelsByProvider: {
|
|
85
|
-
claude: ['claude-fable-5', 'claude-opus-5', 'claude-opus-4-8', 'opus', 'sonnet', 'haiku'],
|
|
86
|
-
codex: CODEX_MODELS,
|
|
87
|
-
gemini: ['gemini-3-flash-preview'],
|
|
88
|
-
grok: ['grok-build', 'grok-composer-2.5-fast'],
|
|
89
|
-
copilot: ['gpt-5-mini'],
|
|
90
|
-
kiro: ['auto', 'gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna', 'claude-sonnet-5', 'claude-opus-5', 'claude-sonnet-4.6', 'deepseek-3.2', 'minimax-m2.5', 'glm-5', 'qwen3-coder-next'],
|
|
91
|
-
},
|
|
92
|
-
effortsByProvider: {
|
|
93
|
-
claude: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
94
|
-
codex: ['low', 'medium', 'high', 'xhigh'],
|
|
95
|
-
gemini: [],
|
|
96
|
-
grok: [],
|
|
97
|
-
copilot: ['low', 'medium', 'high'],
|
|
98
|
-
kiro: ['low', 'medium', 'high', 'xhigh'],
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
78
|
claude: {
|
|
102
79
|
label: 'Claude',
|
|
103
80
|
// Aliases + pinned full IDs (hyphen form — Anthropic API rejects
|
|
@@ -132,14 +109,6 @@ export const CLI_META: Record<string, CliMeta> = {
|
|
|
132
109
|
],
|
|
133
110
|
efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
134
111
|
},
|
|
135
|
-
'claude-e': {
|
|
136
|
-
label: 'Claude E',
|
|
137
|
-
models: [
|
|
138
|
-
'opus', 'sonnet', 'haiku',
|
|
139
|
-
'claude-fable-5', 'claude-sonnet-5', 'claude-opus-5', 'claude-opus-4-8', 'claude-opus-4-7', 'claude-sonnet-4-6', 'claude-haiku-4-5',
|
|
140
|
-
],
|
|
141
|
-
efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
142
|
-
},
|
|
143
112
|
codex: {
|
|
144
113
|
label: 'Codex',
|
|
145
114
|
models: CODEX_MODELS,
|
|
@@ -338,7 +307,7 @@ export function coerceEffortForModel(
|
|
|
338
307
|
}
|
|
339
308
|
|
|
340
309
|
export function metaFor(cli: string, registry?: Record<string, CliMeta> | null): CliMeta {
|
|
341
|
-
if (isRetiredCliSelection(cli)) return { label:
|
|
310
|
+
if (isRetiredCliSelection(cli)) return { label: retiredRuntimeLabel(cli), models: [], efforts: [] };
|
|
342
311
|
return registry?.[cli] || CLI_META[cli] || { label: cli, models: [], efforts: [] };
|
|
343
312
|
}
|
|
344
313
|
|
|
@@ -14,9 +14,7 @@ export type { HbJob, HbSchedule, HbScheduleEvery, HbScheduleCron };
|
|
|
14
14
|
const INTERVAL_RE = /^\d+[smh]$/;
|
|
15
15
|
const HHMM_RE = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
16
16
|
export const TARGET_FALLBACK = [
|
|
17
|
-
'ai-e',
|
|
18
17
|
'claude',
|
|
19
|
-
'claude-e',
|
|
20
18
|
'codex',
|
|
21
19
|
'codex-app',
|
|
22
20
|
'copilot',
|
|
@@ -103,9 +103,6 @@ const sourceHash = (base = project) => {
|
|
|
103
103
|
else fail('Unsupported source entry');
|
|
104
104
|
};
|
|
105
105
|
for (const name of sourceNames(base)) walk(name);
|
|
106
|
-
// Optional native executables are inputs too, never rebuilt by this script.
|
|
107
|
-
for (const name of ['native/claude-e/target/release/jaw-claude-i', 'native/jaw-claude-i/target/release/jaw-claude-i'])
|
|
108
|
-
if (exists(path.join(base, name))) walk(name);
|
|
109
106
|
return hash.digest('hex');
|
|
110
107
|
};
|
|
111
108
|
const preflight = () => {
|
|
@@ -150,13 +147,6 @@ if (op === 'preflight') {
|
|
|
150
147
|
recursive: true, dereference: false, verbatimSymlinks: true,
|
|
151
148
|
filter: p => p !== path.join(project, 'public/dist'),
|
|
152
149
|
});
|
|
153
|
-
for (const name of ['native/claude-e/target/release/jaw-claude-i', 'native/jaw-claude-i/target/release/jaw-claude-i']) {
|
|
154
|
-
if (!exists(path.join(project, name))) continue;
|
|
155
|
-
fs.mkdirSync(path.dirname(path.join(build, 'source', name)), { recursive: true });
|
|
156
|
-
fs.cpSync(path.join(project, name), path.join(build, 'source', name), {
|
|
157
|
-
dereference: false, verbatimSymlinks: true,
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
150
|
if (sourceHash() !== state.sourceSha256 || sourceHash(path.join(build, 'source')) !== state.sourceSha256)
|
|
161
151
|
fail('Source changed during snapshot');
|
|
162
152
|
} else {
|
|
@@ -396,20 +386,6 @@ echo "Verifying better-sqlite3 opens with bundled Node..."
|
|
|
396
386
|
}
|
|
397
387
|
}
|
|
398
388
|
|
|
399
|
-
NATIVE_BIN="$SOURCE_ROOT/native/claude-e/target/release/jaw-claude-i"
|
|
400
|
-
LEGACY_NATIVE_BIN="$SOURCE_ROOT/native/jaw-claude-i/target/release/jaw-claude-i"
|
|
401
|
-
if [ -f "$NATIVE_BIN" ]; then
|
|
402
|
-
echo "Copying jaw-claude-i..."
|
|
403
|
-
cp "$NATIVE_BIN" "$SIDECAR_DIR/bin/jaw-claude-i"
|
|
404
|
-
chmod +x "$SIDECAR_DIR/bin/jaw-claude-i"
|
|
405
|
-
elif [ -f "$LEGACY_NATIVE_BIN" ]; then
|
|
406
|
-
echo "Copying jaw-claude-i from legacy native path..."
|
|
407
|
-
cp "$LEGACY_NATIVE_BIN" "$SIDECAR_DIR/bin/jaw-claude-i"
|
|
408
|
-
chmod +x "$SIDECAR_DIR/bin/jaw-claude-i"
|
|
409
|
-
else
|
|
410
|
-
echo "WARN: jaw-claude-i not found, skipping (optional)"
|
|
411
|
-
fi
|
|
412
|
-
|
|
413
389
|
echo "Creating CLI shims..."
|
|
414
390
|
if [[ "$PLATFORM" == "win32" ]]; then
|
|
415
391
|
cat > "$SIDECAR_DIR/bin/jaw.cmd" << 'SHIM'
|
|
@@ -3,7 +3,8 @@ const { existsSync, readdirSync, readFileSync, readlinkSync, realpathSync, statS
|
|
|
3
3
|
const { isAbsolute, join, relative, resolve, sep } = require('node:path');
|
|
4
4
|
|
|
5
5
|
function retiredPackage(name) {
|
|
6
|
-
return /^(?:jawcode|jwc|bun)$/.test(name)
|
|
6
|
+
return /^(?:jawcode|jwc|bun|claude-e|claude-exec)$/.test(name)
|
|
7
|
+
|| name === '@bitkyc08/ai-e'
|
|
7
8
|
|| /^@(?:jawcode(?:-[^/]+)?|gajae(?:-[^/]+)?|oven)(?:\/|$)/.test(name);
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -13,12 +14,19 @@ function retiredPayloadReason(file) {
|
|
|
13
14
|
const parts = normalized.split('/');
|
|
14
15
|
// Package names are meaningful only directly below node_modules. A normal
|
|
15
16
|
// package may ship a Bun adapter (for example hono/dist/adapter/bun).
|
|
16
|
-
|
|
17
|
+
const atNodeModules = (index) => {
|
|
18
|
+
if (parts[index] !== 'node_modules') return false;
|
|
19
|
+
const first = parts[index + 1] || '';
|
|
20
|
+
if (retiredPackage(first)) return true;
|
|
21
|
+
if (first.startsWith('@')) return retiredPackage(first + '/' + (parts[index + 2] || ''));
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
if (parts.some((_, index) => atNodeModules(index))) {
|
|
17
25
|
return 'retired package or scope';
|
|
18
26
|
}
|
|
19
27
|
if (/(?:^|\/)electron\/sidecar\/jawcode(?:\/|$)/.test(normalized)) return 'retired vendored runtime';
|
|
20
|
-
if (/^(?:bin\/)?(?:bun|jwc)(?:\.(?:cmd|ps1|exe|js))?$/.test(normalized)
|
|
21
|
-
|| /(?:^|\/)node_modules\/\.bin\/(?:bun|jwc)(?:\.(?:cmd|ps1|exe|js))?$/.test(normalized)) {
|
|
28
|
+
if (/^(?:bin\/)?(?:bun|jwc|jaw-claude-i|claude-e|claude-exec)(?:\.(?:cmd|ps1|exe|js))?$/.test(normalized)
|
|
29
|
+
|| /(?:^|\/)node_modules\/\.bin\/(?:bun|jwc|jaw-claude-i|claude-e|claude-exec)(?:\.(?:cmd|ps1|exe|js))?$/.test(normalized)) {
|
|
22
30
|
return 'retired runtime executable';
|
|
23
31
|
}
|
|
24
32
|
if (/(?:^|\/)src\/lib\/tui(?:\/|$)/.test(normalized)) return 'retired TUI assets';
|
|
@@ -179,7 +179,7 @@ async function main(): Promise<void> {
|
|
|
179
179
|
if (!cliRes.ok) throw new Error(`/api/cli-status HTTP ${cliRes.status}`);
|
|
180
180
|
const cliJson = (await cliRes.json()) as Record<string, unknown> | null;
|
|
181
181
|
const keys = Object.keys(cliJson ?? {});
|
|
182
|
-
const required: string[] = ['
|
|
182
|
+
const required: string[] = ['claude', 'codex', 'codex-app', 'copilot', 'cursor', 'kiro-code', 'grok', 'opencode'];
|
|
183
183
|
for (const k of required) {
|
|
184
184
|
if (!keys.includes(k)) throw new Error(`missing cli key in status: ${k}`);
|
|
185
185
|
}
|
package/scripts/install.sh
CHANGED
|
@@ -489,11 +489,6 @@ install_cli_jaw() {
|
|
|
489
489
|
unset CLI_JAW_REQUIRE_CLI_TOOLS 2>/dev/null || true
|
|
490
490
|
unset npm_config_jaw_require_cli_tools 2>/dev/null || true
|
|
491
491
|
fi
|
|
492
|
-
if ! command -v cargo &>/dev/null; then
|
|
493
|
-
export CLAUDE_E_SKIP_BUILD="${CLAUDE_E_SKIP_BUILD:-1}"
|
|
494
|
-
warn "Rust Cargo not found — skipping optional claude-e native helper build"
|
|
495
|
-
warn "Install Rust later and reinstall claude-e if you need the Claude E runtime"
|
|
496
|
-
fi
|
|
497
492
|
eval "$pkg_cmd"
|
|
498
493
|
|
|
499
494
|
hash -r 2>/dev/null || true
|
|
@@ -25,16 +25,6 @@ export function checkPackedFiles(files, manifest) {
|
|
|
25
25
|
export function checkDefaultInstall(manifest, lock, label = 'root') {
|
|
26
26
|
assertRetiredManifestAbsent(manifest, `${label}/package.json`);
|
|
27
27
|
assertRetiredManifestAbsent(lock, `${label}/package-lock.json`);
|
|
28
|
-
// ai-e remains an on-demand provider, never a default installation.
|
|
29
|
-
for (const pkg of [manifest, ...Object.values(lock.packages || {})]) {
|
|
30
|
-
assert.notEqual(pkg.name, '@bitkyc08/ai-e', 'ai-e must not be installed by default');
|
|
31
|
-
for (const field of ['dependencies', 'optionalDependencies']) {
|
|
32
|
-
assert.equal(pkg[field]?.['@bitkyc08/ai-e'], undefined, 'ai-e must remain an on-demand provider');
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
for (const file of Object.keys(lock.packages || {})) {
|
|
36
|
-
assert.ok(!file.replaceAll('\\', '/').endsWith('node_modules/@bitkyc08/ai-e'), 'ai-e must not be in the default install tree');
|
|
37
|
-
}
|
|
38
28
|
}
|
|
39
29
|
|
|
40
30
|
// Exercise the real entrypoint in an owned home. Any attempted child process,
|
|
@@ -119,7 +109,7 @@ function main() {
|
|
|
119
109
|
checkDefaultInstall(manifest, read('package-lock.json'));
|
|
120
110
|
checkDefaultInstall(read('electron/package.json'), read('electron/package-lock.json'), 'electron');
|
|
121
111
|
if (args[0] === '--source-only') {
|
|
122
|
-
console.log('[retired-runtime-package:source-only] PASS root/electron manifests and locks
|
|
112
|
+
console.log('[retired-runtime-package:source-only] PASS root/electron manifests and locks');
|
|
123
113
|
console.log('[retired-runtime-package:source-only] packed NOT RUN; CLI NOT RUN; staged NOT RUN');
|
|
124
114
|
return;
|
|
125
115
|
}
|
|
@@ -139,7 +129,7 @@ function main() {
|
|
|
139
129
|
assert.equal(entries.length, 1, 'expected one npm package');
|
|
140
130
|
checkPackedFiles(entries[0].files, manifest);
|
|
141
131
|
checkRetiredCommand(join(repoRoot, 'dist/bin/cli-jaw.js'));
|
|
142
|
-
console.log('[retired-runtime-package] PASS manifest, lock, packed files and retired CLI
|
|
132
|
+
console.log('[retired-runtime-package] PASS manifest, lock, packed files and retired CLI');
|
|
143
133
|
}
|
|
144
134
|
|
|
145
135
|
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) main();
|
|
@@ -32,18 +32,6 @@ run_version() {
|
|
|
32
32
|
ok "$name works: $resolved"
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
run_optional_version() {
|
|
36
|
-
local name="$1"
|
|
37
|
-
if command -v "$name" >/dev/null 2>&1 && "$name" --version >/dev/null 2>&1; then
|
|
38
|
-
ok "$name works: $(command -v "$name")"
|
|
39
|
-
return 0
|
|
40
|
-
fi
|
|
41
|
-
if [ "${CLI_JAW_REQUIRE_OPTIONAL_RUNTIMES:-0}" = "1" ] || [ "${CLI_JAW_REQUIRE_OPTIONAL_RUNTIMES:-}" = "true" ]; then
|
|
42
|
-
fail "$name optional runtime is missing or not runnable"
|
|
43
|
-
fi
|
|
44
|
-
ok "$name optional runtime not available; continuing"
|
|
45
|
-
}
|
|
46
|
-
|
|
47
35
|
path_contains() {
|
|
48
36
|
local needle="$1"
|
|
49
37
|
case ":${PATH:-}:" in
|
|
@@ -83,8 +71,6 @@ ok "node version is >=22: $(node --version)"
|
|
|
83
71
|
run_version npm
|
|
84
72
|
run_version jaw
|
|
85
73
|
run_version cli-jaw
|
|
86
|
-
run_optional_version ai-e
|
|
87
|
-
run_optional_version claude-e
|
|
88
74
|
|
|
89
75
|
if command -v npm >/dev/null 2>&1; then
|
|
90
76
|
npm_prefix="$(npm prefix -g 2>/dev/null || true)"
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { broadcast } from '../core/bus.js';
|
|
2
|
-
export function isJawRuntimeEvent(raw) {
|
|
3
|
-
return typeof raw === 'object' && raw !== null && raw['type'] === 'jaw_runtime';
|
|
4
|
-
}
|
|
5
|
-
export function handleJawRuntimeEvent(event, _agentLabel) {
|
|
6
|
-
const eventName = String(event['event'] || '');
|
|
7
|
-
const runId = String(event['run_id'] || '');
|
|
8
|
-
const seq = Number(event['seq'] || 0);
|
|
9
|
-
// Internal runtime traces — 'internal' keeps them off WS clients and the
|
|
10
|
-
// SSE dual-emit path.
|
|
11
|
-
switch (eventName) {
|
|
12
|
-
case 'runtime_started':
|
|
13
|
-
broadcast('agent:claude-e:runtime_started', { runId, seq, version: event['helperVersion'] }, 'internal');
|
|
14
|
-
break;
|
|
15
|
-
case 'claude_spawned':
|
|
16
|
-
broadcast('agent:claude-e:spawned', { runId, pid: event['pid'] }, 'internal');
|
|
17
|
-
break;
|
|
18
|
-
case 'session_started':
|
|
19
|
-
broadcast('agent:claude-e:session', { runId, sessionId: event['sessionId'], transcriptPath: event['transcriptPath'] }, 'internal');
|
|
20
|
-
break;
|
|
21
|
-
case 'prompt_injected':
|
|
22
|
-
broadcast('agent:claude-e:prompt_injected', { runId }, 'internal');
|
|
23
|
-
break;
|
|
24
|
-
case 'stop_received':
|
|
25
|
-
broadcast('agent:claude-e:stop', { runId, transcriptPath: event['transcriptPath'] }, 'internal');
|
|
26
|
-
break;
|
|
27
|
-
case 'stop_failure':
|
|
28
|
-
broadcast('agent:claude-e:stop_failure', { runId, error: event['error'] }, 'internal');
|
|
29
|
-
break;
|
|
30
|
-
case 'interrupted':
|
|
31
|
-
broadcast('agent:claude-e:interrupted', { runId, sessionId: event['sessionId'], resumable: event['resumable'] }, 'internal');
|
|
32
|
-
break;
|
|
33
|
-
case 'cleanup_started':
|
|
34
|
-
case 'cleanup_done':
|
|
35
|
-
broadcast('agent:claude-e:cleanup', { runId, event: eventName, escalated: event['escalated'] }, 'internal');
|
|
36
|
-
break;
|
|
37
|
-
case 'error':
|
|
38
|
-
broadcast('agent:claude-e:error', { runId, message: event['message'], exitCode: event['exitCode'] }, 'internal');
|
|
39
|
-
break;
|
|
40
|
-
default:
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=claude-e-runtime.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"claude-e-runtime.js","sourceRoot":"","sources":["../../../src/agent/claude-e-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC1C,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAK,GAA+B,CAAC,MAAM,CAAC,KAAK,aAAa,CAAC;AACjH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAA8B,EAAE,WAAmB;IACrF,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtC,yEAAyE;IACzE,sBAAsB;IACtB,QAAQ,SAAS,EAAE,CAAC;QAChB,KAAK,iBAAiB;YAClB,SAAS,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,eAAe,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YACzG,MAAM;QACV,KAAK,gBAAgB;YACjB,SAAS,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAC9E,MAAM;QACV,KAAK,iBAAiB;YAClB,SAAS,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,gBAAgB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YACnI,MAAM;QACV,KAAK,iBAAiB;YAClB,SAAS,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;YACnE,MAAM;QACV,KAAK,eAAe;YAChB,SAAS,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,CAAC,gBAAgB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YACjG,MAAM;QACV,KAAK,cAAc;YACf,SAAS,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YACvF,MAAM;QACV,KAAK,aAAa;YACd,SAAS,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAC7H,MAAM;QACV,KAAK,iBAAiB,CAAC;QACvB,KAAK,cAAc;YACf,SAAS,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAC5G,MAAM;QACV,KAAK,OAAO;YACR,SAAS,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YACjH,MAAM;QACV;YACI,MAAM;IACd,CAAC;AACL,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./cli-engine-Bw0QTAVX.js";import{n}from"./settings-types-D3cd6SWy.js";import{t as r}from"./react-C_pPTFsM.js";import{t as i}from"./jsx-runtime-NZYk81nU.js";import{t as a}from"./settings-client-CmwRsVd1.js";import{t as o}from"./error-normalize-CL69Bl7z.js";import{a as s,i as c,n as l,r as u,t as d}from"./page-shell-BeGD0rRQ.js";import{i as f,s as p}from"./fields-mlGpofqQ.js";import{n as m,o as h,r as ee,s as g}from"./Permissions-DzNJCt8K.js";import{a as _,c as v,d as y,i as te,l as b,n as ne,o as x,r as re,s as ie,t as ae,u as S}from"./agent-meta-BWHASq1a.js";import{t as C}from"./path-utils-B6vBr0DD.js";var w=e(r(),1),oe=1e3,se=8e3,ce=9e4;function T(e,t){if(!e||!t)return!1;let n=e[t]?.probeState;return n?n===`checking`||n===`failing`:!1}function le(e){let t=oe*2**Math.min(Number.isFinite(e)&&e>0?Math.floor(e):0,8);return Math.min(Math.max(t,oe),se)}function ue(e){let{snapshot:t,cli:n,attempts:r,now:i,deadline:a}=e;if(!T(t,n))return{kind:`stop`};if(i>=a||r>=24)return{kind:`exhausted`};let o=t?.[n]?.nextRetryAt,s=typeof o==`number`&&o>i?o:i+le(r);return{kind:`wait`,delayMs:Math.max(Math.min(s,a)-i,0)}}var E=i();function de({cli:e,cliOptions:n,provider:r=``,providerOptions:i=[],model:a,modelOptions:o,effort:s,effortOptions:l,workingDir:u,workingDirError:d,cliMeta:m,onCliChange:h,onProviderChange:ee,onModelChange:g,onEffortChange:y,onWorkingDirChange:te}){let b=v(n),x=t(e),re=b.filter(e=>ne.includes(e)).length;return(0,E.jsx)(c,{title:`Agent runtime`,hint:`Active CLI, model, effort, and workspace used by this instance.`,children:(0,E.jsxs)(`div`,{className:`settings-agent-runtime-grid`,children:[(0,E.jsx)(f,{id:`agent-cli`,label:`Active CLI`,value:e,missingValueLabel:x?`JWC (retired)`:void 0,error:x?`This runtime is retired. Select an available runtime to continue.`:null,options:b.map(e=>({value:e,label:_(e,m).label||e})),collapsedAfter:re,onChange:h}),i.length>0?(0,E.jsx)(f,{id:`agent-${e}-provider`,label:`Provider`,value:r,options:i.map(e=>({value:e,label:e})),onChange:e=>ee?.(e)}):null,(0,E.jsx)(f,{id:`agent-model`,label:`Active model`,value:a,disabled:x,options:o.length>0?o:[{value:``,label:`(default)`}],onChange:g}),(0,E.jsx)(f,{id:`agent-effort`,label:`Effort`,value:s,options:[{value:``,label:`(default)`},...l.map(e=>({value:e,label:e}))],disabled:x||l.length===0,onChange:y}),(0,E.jsx)(p,{id:`agent-workingDir`,label:`Working directory`,value:u,error:d,placeholder:`/path/to/project`,onChange:te})]})})}var D=[{value:`auto`,label:`Auto (YOLO)`},{value:`safe`,label:`Safe`},{value:`custom`,label:`Custom allowlist`}];function fe({value:e,configuredValue:t,onChange:n}){let r=h(e),i=r.mode===`custom`?`custom`:r.mode===`safe`?`safe`:`auto`,a=r.mode===`custom`?r.tokens:[],o=r.mode===`custom`?`Editor draft: ${a.length} explicit token${a.length===1?``:`s`}`:null;return(0,E.jsxs)(c,{title:`Permissions`,hint:`Selecting a value changes the draft. Save applies it. Auto (YOLO) requests automatic approval or permission bypass. Behavior varies by runtime.`,children:[(0,E.jsx)(f,{id:`agent-permissions-mode`,label:`Change policy to`,value:i,options:D,onChange:e=>{n(e===`auto`?`auto`:e===`safe`?`safe`:a.length>0&&ee(a)?a:g(null))}}),o?(0,E.jsx)(`p`,{className:`settings-agent-note`,children:o}):null,(0,E.jsxs)(`p`,{className:`settings-agent-note`,id:`agent-configured-policy`,children:[`Configured policy: `,m(t)]})]})}function pe({activeCli:e,flushCli:n,flushModel:r,cliOptions:i,modelOptions:a,cliMeta:o,loading:s,error:l,onFlushCliChange:u,onFlushModelChange:d}){let p=n||e,m=p?_(p,o).label||p:`active`;return(0,E.jsx)(c,{title:`Flush Agent`,hint:`Separate summary agent used for context flush and compact work.`,children:(0,E.jsxs)(`details`,{className:`settings-agent-flush`,children:[(0,E.jsxs)(`summary`,{children:[(0,E.jsx)(`span`,{children:`Flush runtime`}),(0,E.jsxs)(`code`,{children:[m,r&&r!=="default"?` / ${r}`:``]})]}),s?(0,E.jsx)(`p`,{className:`settings-agent-note`,children:`Loading flush settings...`}):null,l?(0,E.jsx)(`p`,{className:`settings-field-error`,role:`alert`,children:l}):null,(0,E.jsxs)(`div`,{className:`settings-agent-runtime-grid`,children:[(0,E.jsx)(f,{id:`agent-flush-cli`,label:`Flush CLI`,value:n,missingValueLabel:t(n)?`JWC (retired)`:void 0,error:t(p)?`The saved flush runtime is retired. Choose an available runtime.`:null,options:[{value:``,label:`(active CLI)`},...y(i).map(e=>({value:e,label:_(e,o).label||e}))],onChange:u}),(0,E.jsx)(f,{id:`agent-flush-model`,label:`Flush model`,value:r,disabled:t(p),options:[{value:``,label:`(default)`},...a],onChange:d})]})]})})}function O(e){return e.source===`static`||e.id.startsWith(`static:`)}function me(){return`new:${Date.now().toString(36)}:${Math.random().toString(36).slice(2,8)}`}function he(e,t){let n=y(e)[0]||`claude`,r=t?.[n]?.models?.[0]||`default`;return{id:me(),name:`New Agent`,cli:n,model:r,role:``,status:`idle`,source:`db`}}function ge(e){return Array.isArray(e)?e.map(k).filter(Boolean):e.data.map(k).filter(Boolean)}function k(e){if(!e||typeof e!=`object`)return null;let t=e,n=typeof t.id==`string`?t.id:``,r=typeof t.name==`string`?t.name:``;if(!n||!r)return null;let i=t.source===`static`||n.startsWith(`static:`)?`static`:`db`,a={id:n,name:r,cli:typeof t.cli==`string`&&t.cli?t.cli:`claude`,model:typeof t.model==`string`&&t.model?t.model:`default`,role:typeof t.role==`string`?t.role:``,source:i};return typeof t.status==`string`&&(a.status=t.status),a}function A(e){return e.name.trim()?e.cli.trim()?e.model.trim()?null:`Model is required`:`CLI is required`:`Name is required`}function j(e){return e.some(e=>A(e)!==null)}function _e(e,t){return JSON.stringify(e.map(I))===JSON.stringify(t.map(I))}function M(e,t){let n=new Map(e.map(e=>[e.id,e])),r=new Set(t.map(e=>e.id)),i=[],a=[],o=[];for(let e of t){let t=n.get(e.id);if(!t||e.id.startsWith(`new:`)){i.push(e);continue}let r=P(t,e);Object.keys(r).length>0&&a.push({before:t,after:e,patch:r})}for(let t of e)!r.has(t.id)&&!O(t)&&o.push(t);return{added:i,updated:a,removed:o}}function N(e,t){let n=M(e,t);return{added:n.added.length,updated:n.updated.length,removed:n.removed.length}}async function ve(e,t,n){let r=M(t,n);for(let t of r.removed)await e.delete(`/api/employees/${encodeURIComponent(t.id)}`);for(let t of r.added)await e.post(`/api/employees`,F(t));for(let t of r.updated)await e.put(`/api/employees/${encodeURIComponent(t.after.id)}`,t.patch)}function P(e,t){if(O(t))return e.model===t.model?{}:{model:t.model};let n={};for(let r of[`name`,`cli`,`model`,`role`,`status`])(e[r]||``)!==(t[r]||``)&&(n[r]=t[r]||``);return n}function F(e){return{name:e.name.trim()||`New Agent`,cli:e.cli.trim()||`claude`,model:e.model.trim()||`default`,role:e.role.trim()}}function I(e){let t={id:e.id,name:e.name,cli:e.cli,model:e.model,role:e.role,source:e.source};return e.status!==void 0&&(t.status=e.status),t}function L({employee:e,index:n,cliOptions:r,cliMeta:i,onChange:a,onRemove:o}){let s=O(e),c=_(e.cli,i),l=ie(c.models,e.model),u=A(e),d=t(e.cli),m=y(Array.from(new Set([...r,e.cli,`claude`])).filter(Boolean));return(0,E.jsxs)(`fieldset`,{className:`settings-runtime-employee-row`,children:[(0,E.jsxs)(`legend`,{children:[e.name||`Employee ${n+1}`,s?(0,E.jsx)(`span`,{children:`static`}):null]}),(0,E.jsxs)(`div`,{className:`settings-runtime-employee-grid`,children:[(0,E.jsx)(p,{id:`runtime-employee-${e.id}-name`,label:`Name`,value:e.name,disabled:s,error:u===`Name is required`?u:null,onChange:e=>a({name:e})}),(0,E.jsx)(f,{id:`runtime-employee-${e.id}-cli`,label:`CLI`,value:e.cli,missingValueLabel:d?`JWC (retired)`:void 0,error:d?`This saved runtime cannot execute. Choose an available runtime.`:null,disabled:s,options:m.map(e=>({value:e,label:_(e,i).label||e})),onChange:e=>{a({cli:e,model:_(e,i).models[0]||`default`})}}),(0,E.jsx)(f,{id:`runtime-employee-${e.id}-model`,label:`Model`,value:e.model,disabled:d,options:l.length>0?l:[{value:`default`,label:`default`}],onChange:e=>a({model:e})}),(0,E.jsx)(p,{id:`runtime-employee-${e.id}-role`,label:`Role`,value:e.role,disabled:s,onChange:e=>a({role:e})})]}),(0,E.jsxs)(`div`,{className:`settings-runtime-employee-footer`,children:[(0,E.jsxs)(`span`,{children:[e.source,e.status?` / ${e.status}`:``]}),(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,disabled:s,onClick:o,"aria-label":`Remove employee ${e.name||n+1}`,children:`Remove`})]})]})}function ye({roster:e,original:t,cliOptions:n,cliMeta:r,loading:i,error:a,onRosterChange:o}){let s=N(t,e),l=j(e);function u(t,n){o(e.map((e,r)=>r===t?{...e,...n}:e))}function d(t){o(e.filter((e,n)=>n!==t))}return(0,E.jsxs)(c,{title:`Employees`,hint:`Runtime dispatch roster. Static employees keep their locked identity; database employees can be edited.`,children:[(0,E.jsxs)(`div`,{className:`settings-runtime-employee-summary`,children:[(0,E.jsxs)(`span`,{children:[`+`,s.added]}),(0,E.jsxs)(`span`,{children:[`~`,s.updated]}),(0,E.jsxs)(`span`,{children:[`-`,s.removed]}),l?(0,E.jsx)(`strong`,{children:`Fix invalid rows before saving.`}):null]}),i?(0,E.jsx)(`p`,{className:`settings-agent-note`,children:`Loading employees...`}):null,a?(0,E.jsx)(`p`,{className:`settings-field-error`,role:`alert`,children:a}):null,e.length===0?(0,E.jsx)(`p`,{className:`settings-empty`,children:`No runtime employees configured.`}):(0,E.jsx)(`div`,{className:`settings-runtime-employee-list`,children:e.map((e,t)=>(0,E.jsx)(L,{employee:e,index:t,cliOptions:n,cliMeta:r??null,onChange:e=>u(t,e),onRemove:()=>d(t)},e.id))}),(0,E.jsx)(`div`,{className:`settings-employee-footer-bar`,children:(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,onClick:()=>o([...e,he(n,r)]),children:`+ Add employee`})})]})}var R=new Set([`runtimeEmployees`,`flushCli`,`flushModel`]);function z(e){let t={},n=null,r=null;for(let[i,a]of Object.entries(e))i===`runtimeEmployees`?r=a:i===`flushCli`||i===`flushModel`?(n??={},n[i===`flushCli`?`cli`:`model`]=String(a??``)):R.has(i)||(t[i]=a);return{settingsBundle:t,flushPatch:n,runtimeEmployeesNext:r}}async function be(e){let{client:t,bundle:n,employeeDraft:r,employeeOriginal:i}=e;if(j(r))throw Error(`runtime employees: fix invalid rows before saving`);let{settingsBundle:a,flushPatch:o,runtimeEmployeesNext:s}=z(n),c=null;try{if(Object.keys(a).length>0){let e=await t.put(`/api/settings`,C(a));c=e&&typeof e==`object`&&`data`in e?e.data:e}}catch(e){throw Error(`settings save failed: ${e instanceof Error?e.message:String(e)}`)}try{o&&await t.put(`/api/memory-files/settings`,o)}catch(e){throw Error(`flush settings save failed: ${e instanceof Error?e.message:String(e)}`)}try{if(s){let e=i;try{let n=ge(await t.get(`/api/employees`)),r=new Set(i.map(e=>e.id)),a=new Set(s.map(e=>e.id));e=n.filter(e=>r.has(e.id)||a.has(e.id))}catch{}await ve(t,e,s)}}catch(e){throw Error(`runtime employees save failed: ${e instanceof Error?e.message:String(e)}`)}return c}function xe({status:e,exhausted:t=!1}){if(t)return(0,E.jsx)(`div`,{className:`settings-inline-notice`,role:`alert`,children:`상태 확인이 끝나지 않았습니다. 새로고침하거나 잠시 후 다시 확인하세요.`});if(!e)return null;let r=n(e);return r.kind===`checking`?(0,E.jsx)(`div`,{className:`settings-inline-notice`,role:`status`,"aria-live":`polite`,children:`상태 확인 중`}):r.kind===`unknown`?(0,E.jsx)(`div`,{className:`settings-inline-notice`,role:`alert`,children:r.message}):r.kind===`failing`?(0,E.jsxs)(`div`,{className:`settings-inline-notice`,role:`alert`,children:[`상태 확인 실패 (재시도 중)`,e.probeError?`: ${e.probeError}`:``]}):null}function B(e){if(!(e instanceof a)||e.status!==409)return null;try{return JSON.parse(e.detail).settings??null}catch{return null}}function Se({port:e,client:t,dirty:n,registerSave:r}){let{state:i,refresh:a,setData:c}=s(t,`/api/settings`),[f,p]=(0,w.useState)({cli:``,provider:``,model:``,effort:``,workingDir:``,permissions:`auto`}),[m,ee]=(0,w.useState)({}),[g,v]=(0,w.useState)({}),[ne,C]=(0,w.useState)(!0),[oe,se]=(0,w.useState)(null),[T,le]=(0,w.useState)([]),[D,O]=(0,w.useState)([]),[me,he]=(0,w.useState)(!0),[k,A]=(0,w.useState)(null),[M,N]=(0,w.useState)(null),[ve,P]=(0,w.useState)({}),[F,I]=(0,w.useState)(!1),[L,R]=(0,w.useState)(null),[z,Se]=(0,w.useState)(!1),[Ce,we]=(0,w.useState)(null),V=(0,w.useCallback)(async()=>{try{let e=await t.get(`/api/cli-registry`),n=e&&typeof e==`object`&&`data`in e?e.data:e;N(x(n))}catch{N(null)}},[t]),H=(0,w.useRef)(0),Te=(0,w.useRef)({}),[Ee,De]=(0,w.useState)(!1),U=(0,w.useCallback)(async e=>{try{let n=await t.get(`/api/cli-status`);if(e!==void 0&&e!==H.current)return;Te.current=n,P(n)}catch{if(e!==void 0&&e!==H.current)return;Te.current={},P({})}},[t]),W=(0,w.useCallback)(async()=>{C(!0),se(null);try{let e=await t.get(`/api/memory-files`),n={cli:e.cli||``,model:e.model||``};ee(n),v(n)}catch(e){se(e instanceof Error?e.message:String(e))}finally{C(!1)}},[t]),G=(0,w.useCallback)(async()=>{he(!0),A(null);try{let e=ge(await t.get(`/api/employees`));le(e),O(e)}catch(e){A(e instanceof Error?e.message:String(e))}finally{he(!1)}},[t]);(0,w.useEffect)(()=>{V(),U(),W(),G()},[V,U,G,W]),(0,w.useEffect)(()=>{if(!f.cli)return;let e=H.current+1;H.current=e,De(!1);let t=Date.now()+ce,n=0,r,i=()=>{if(e!==H.current)return;let a=ue({snapshot:Te.current,cli:f.cli,attempts:n,now:Date.now(),deadline:t});if(a.kind!==`stop`){if(a.kind===`exhausted`){De(!0);return}r=setTimeout(()=>{e===H.current&&(n+=1,U(e).then(()=>{e===H.current&&i()}))},a.delayMs)}};return i(),()=>{H.current=e+1,r!==void 0&&clearTimeout(r)}},[f.cli,U]),(0,w.useEffect)(()=>{if(i.kind!==`ready`)return;let e=Object.keys(i.data.perCli||{}),t=i.data.cli||e[0]||``,n=h(i.data.permissions),r=_(t,M);p({cli:t,provider:i.data.perCli?.[t]?.provider||r.defaultProvider||``,model:S(t,i.data.perCli,i.data.activeOverrides),effort:b(t,i.data.perCli,i.data.activeOverrides),workingDir:i.data.workingDir||``,permissions:n.mode===`custom`?n.tokens:n.mode===`safe`?`safe`:`auto`})},[M,i]),(0,w.useEffect)(()=>()=>{for(let e of Array.from(n.pending.keys()))(e===`cli`||e===`workingDir`||e===`permissions`||e===`runtimeEmployees`||e===`flushCli`||e===`flushModel`||e.startsWith(`activeOverrides.`))&&n.remove(e)},[n]);let K=(0,w.useCallback)((e,t)=>n.set(e,t),[n]),Oe=(0,w.useCallback)(async()=>{let e=n.saveBundle();if(Object.keys(e).length===0)return;let r=await be({client:t,bundle:e,employeeDraft:D,employeeOriginal:T});n.clear(),r&&c(r),await a(),await V(),await W(),await G()},[t,n,D,T,V,G,W,a,c]);(0,w.useEffect)(()=>{if(r)return r(Oe),()=>r(null)},[r,Oe]);let q=i.kind===`ready`?i.data:{},J=q.perCli||{},Y=q.activeOverrides||{},ke=(0,w.useMemo)(()=>{let e=y(Object.keys(J));return e.length?e:y(Object.keys(M||ae))},[J,M]),X=_(f.cli,M),Z=f.provider||X.defaultProvider||X.providers?.[0]||``,Ae=f.cli===`pi`,Q=!Ae&&(X.providers?.length??0)>0,je=ie(Q&&X.modelsByProvider?.[Z]||X.models,f.model),Me=Q?te(X,f.model,X.effortsByProvider?.[Z]||X.efforts,Z):te(X,f.model),Ne=f.workingDir.trim()?null:`Required`,Pe=(0,w.useCallback)(async e=>{I(!0),R(null);try{let n=await t.post(`/api/settings/runtime-default-migration`,{action:e}),r;r=`settings`in n&&n.settings?n.settings:`data`in n&&n.data?n.data:n,c(r)}catch(e){let t=B(e);if(t){c(t);return}R(o(e))}finally{I(!1)}},[t,c]),Fe=(0,w.useCallback)(async e=>{Se(!0),we(null);try{let n=await t.post(`/api/settings/multi-session-default-migration`,{action:e}),r;r=`settings`in n&&n.settings?n.settings:`data`in n&&n.data?n.data:n,c(r)}catch(e){let t=B(e);if(t){c(t);return}we(o(e))}finally{Se(!1)}},[t,c]);if(i.kind===`loading`)return(0,E.jsx)(l,{});if(i.kind===`offline`)return(0,E.jsx)(u,{port:e});if(i.kind===`error`)return(0,E.jsx)(d,{message:i.message});function Ie(){for(let e of Array.from(n.pending.keys()))e.startsWith(`activeOverrides.`)&&n.remove(e)}function $(e){p(e)}return(0,E.jsxs)(`form`,{className:`settings-page-form`,onSubmit:e=>{e.preventDefault(),Oe()},children:[q.runtimeDefaultMigration?.state===`pending`?(0,E.jsxs)(`div`,{className:`settings-inline-notice`,role:`status`,children:[(0,E.jsx)(`strong`,{children:`기본 런타임 변경 안내`}),(0,E.jsx)(`p`,{children:`기존 선택은 유지됩니다. Codex App으로 전환하거나 현재 런타임을 계속 사용할 수 있습니다.`}),(0,E.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,disabled:F,onClick:()=>void Pe(`accept`),children:`Codex App 사용`}),(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-secondary`,disabled:F,onClick:()=>void Pe(`keep`),children:`현재 런타임 유지`})]}),L?(0,E.jsx)(`span`,{className:`settings-field-error`,role:`alert`,children:L}):null]}):null,q.multiSessionDefaultMigration?.state===`pending`?(0,E.jsxs)(`div`,{className:`settings-inline-notice`,role:`status`,children:[(0,E.jsx)(`strong`,{children:`다중 세션 안내`}),(0,E.jsx)(`p`,{children:`대화 세션을 여러 개 열 수 있습니다. 켜면 동시 실행도 2로 올라가서, 두 번째 세션이 첫 번째가 끝나기를 기다리지 않습니다. 지금 설정은 그대로 유지됩니다.`}),(0,E.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,disabled:z,onClick:()=>void Fe(`accept`),children:`다중 세션 켜기`}),(0,E.jsx)(`button`,{type:`button`,className:`settings-action settings-action-secondary`,disabled:z,onClick:()=>void Fe(`keep`),children:`지금 설정 유지`})]}),Ce?(0,E.jsx)(`span`,{className:`settings-field-error`,role:`alert`,children:Ce}):null]}):null,(0,E.jsxs)(`label`,{className:`settings-field settings-field-select`,htmlFor:`midrun-policy-select`,children:[(0,E.jsx)(`span`,{className:`settings-field-label`,children:`실행 중 메시지 처리 (mid-run policy)`}),(0,E.jsxs)(`select`,{id:`midrun-policy-select`,value:String(q.multiSession?.midRunPolicy||`steer`),onChange:e=>{let t=e.target.value;K(`multiSession.midRunPolicy`,{value:t,original:String(q.multiSession?.midRunPolicy||`steer`),valid:!0})},children:[(0,E.jsx)(`option`,{value:`steer`,children:`steer (기본) — 실행 중 지시 변경`}),(0,E.jsx)(`option`,{value:`followup`,children:`followup — 끝나면 순서대로 실행`}),(0,E.jsx)(`option`,{value:`collect`,children:`collect — 모아서 한 번에 실행`}),(0,E.jsx)(`option`,{value:`interrupt`,children:`interrupt — 현재 실행을 중단하고 즉시 실행`})]}),(0,E.jsx)(`span`,{className:`settings-field-hint`,children:`다중 세션이 켜져 있을 때 적용됩니다. codex-app은 같은 턴에 입력을 전달합니다. Cursor·Grok의 native 모드는 현재 요청의 취소와 정리가 끝난 뒤 같은 세션에 다시 요청합니다(cancel-reprompt). 그 외 런타임은 중단 후 새 실행으로 이어갑니다(kill-steer). 보존되는 맥락은 런타임에 따라 다릅니다. 끝난 뒤 실행하려면 followup을 선택하세요.`})]}),(0,E.jsx)(xe,{status:ve[f.cli],exhausted:Ee}),(0,E.jsx)(de,{cli:f.cli,cliOptions:ke,provider:Z,providerOptions:Ae?[]:X.providers||[],model:f.model,modelOptions:je,effort:f.effort,effortOptions:Me,workingDir:f.workingDir,workingDirError:Ne,cliMeta:M,onCliChange:e=>{let t=_(e,M),n={...f,cli:e,provider:J[e]?.provider||t.defaultProvider||``,model:S(e,J,Y),effort:b(e,J,Y)};Ie(),$(n),K(`cli`,{value:e,original:q.cli||``,valid:!0})},onProviderChange:e=>{let t=X.modelsByProvider?.[e]||[],n=X.effortsByProvider?.[e]||[],r=t.includes(f.model)?f.model:t[0]||``,i=re(X,r,f.effort,n,e);$({...f,provider:e,model:r,effort:i}),K(`perCli.${f.cli}.provider`,{value:e,original:J[f.cli]?.provider||X.defaultProvider||``,valid:!0}),K(`activeOverrides.${f.cli}.model`,{value:r,original:S(f.cli,J,Y),valid:r.trim().length>0}),K(`activeOverrides.${f.cli}.effort`,{value:i,original:b(f.cli,J,Y),valid:!0})},onModelChange:e=>{let t=re(X,e,f.effort,Q?X.effortsByProvider?.[Z]||X.efforts:void 0,Q?Z:void 0);$({...f,model:e,effort:t}),K(`activeOverrides.${f.cli}.model`,{value:e,original:S(f.cli,J,Y),valid:e.trim().length>0}),t!==f.effort&&K(`activeOverrides.${f.cli}.effort`,{value:t,original:b(f.cli,J,Y),valid:!0})},onEffortChange:e=>{$({...f,effort:e}),K(`activeOverrides.${f.cli}.effort`,{value:e,original:b(f.cli,J,Y),valid:!0})},onWorkingDirChange:e=>{$({...f,workingDir:e}),K(`workingDir`,{value:e,original:q.workingDir||``,valid:e.trim().length>0})}}),(0,E.jsx)(fe,{value:f.permissions,configuredValue:q.permissions,onChange:e=>{$({...f,permissions:e}),K(`permissions`,{value:e,original:q.permissions??`auto`,valid:e===`auto`||e.length>0})}}),(0,E.jsx)(pe,{activeCli:f.cli,flushCli:g.cli||``,flushModel:g.model||``,cliOptions:ke,cliMeta:M,modelOptions:ie(_(g.cli||f.cli,M).models,g.model||``),loading:ne,error:oe,onFlushCliChange:e=>{let t=e&&_(e,M).models[0]||``;v({cli:e,model:t}),K(`flushCli`,{value:e,original:m.cli||``,valid:!0}),K(`flushModel`,{value:t,original:m.model||``,valid:!0})},onFlushModelChange:e=>{v({...g,model:e}),K(`flushModel`,{value:e,original:m.model||``,valid:!0})}}),(0,E.jsx)(ye,{roster:D,original:T,cliOptions:ke,cliMeta:M,loading:me,error:k,onRosterChange:e=>{if(O(e),_e(e,T)){n.remove(`runtimeEmployees`);return}n.set(`runtimeEmployees`,{value:e,original:T,valid:!j(e)})}})]})}export{xe as CliProbeNotice,B as conflictSettingsFromError,Se as default,z as splitAgentSaveBundle};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-C_pPTFsM.js";import{t as n}from"./jsx-runtime-NZYk81nU.js";import{i as r}from"./page-shell-BeGD0rRQ.js";var i=e(t(),1),a=n(),o=[`employees`],s=[`ai-e`,`claude`,`claude-e`,`codex`,`codex-app`,`copilot`,`cursor`,`kiro-code`,`gemini`,`grok`,`opencode`],c=0;function l(){return c+=1,`emp_${Date.now().toString(36)}_${c}`}function u(){let e=globalThis.crypto;if(e&&typeof e.randomUUID==`function`)try{return e.randomUUID()}catch{}return l()}function d(e=u()){return{id:e,name:``,cli:`claude`,role:``,prompt:``,active:!0}}function f(e){if(!Array.isArray(e))return[];let t=[],n=0;for(let r of e){if(typeof r==`string`){n+=1,t.push({...d(`emp_legacy_${n}`),name:r});continue}if(!r||typeof r!=`object`)continue;let e=r,i=typeof e.name==`string`?e.name:``;if(!i&&!e.id)continue;n+=1;let a=typeof e.id==`string`&&e.id.trim()?e.id.trim():`emp_unknown_${n}`,o=typeof e.cli==`string`&&e.cli.trim()?e.cli.trim():`claude`,s=typeof e.role==`string`?e.role:``,c=typeof e.prompt==`string`?e.prompt:``,l=e.active!==!1;t.push({id:a,name:i,cli:o,role:s,prompt:c,active:l})}return t}function p(e){return e.name.trim()?e.cli.trim()?null:`CLI is required`:`Name is required`}function m(e){return e.some(e=>p(e)!==null)}function h(e){let t=new Map;for(let n of e){let e=n.name.trim().toLowerCase();e&&t.set(e,(t.get(e)??0)+1)}let n=new Set;for(let[e,r]of t)r>1&&n.add(e);return n}function g(e){return e.map(e=>{let t={id:e.id,name:e.name.trim(),cli:e.cli.trim()||`claude`,role:e.role.trim(),active:e.active};return e.prompt.trim()&&(t.prompt=e.prompt),t})}function _({registerSave:e}){return(0,i.useEffect)(()=>{if(e)return e(null),()=>e(null)},[e]),(0,a.jsx)(`form`,{className:`settings-page-form`,onSubmit:e=>e.preventDefault(),children:(0,a.jsx)(r,{title:`Employees`,hint:`Runtime employees are now managed from the Agent page.`,children:(0,a.jsx)(`p`,{className:`settings-section-hint`,children:`Open Runtime / Agent to edit dispatchable employees, static employee model overrides, and database-backed employees in one place.`})})})}export{s as DEFAULT_CLI_OPTIONS,o as EMPLOYEE_KEYS,_ as default,h as duplicateNameSet,p as employeeRowError,m as employeesHaveErrors,d as makeDefaultEmployee,u as newEmployeeId,f as normalizeEmployees,g as toPersistShape};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./cli-engine-Bw0QTAVX.js";import{t as n}from"./react-C_pPTFsM.js";import{t as r}from"./jsx-runtime-NZYk81nU.js";import{a as i,i as a,n as o,r as s,t as c}from"./page-shell-BeGD0rRQ.js";import{a as l,i as u,s as d}from"./fields-mlGpofqQ.js";import{a as f,d as p}from"./agent-meta-BWHASq1a.js";import{t as m}from"./path-utils-B6vBr0DD.js";var h=e(n(),1),g=r(),_=[{value:`every`,label:`every (interval)`},{value:`cron`,label:`cron expression`}];function v({job:e,index:t,bodyError:n,timeZoneError:r,onChange:i,onRemove:a}){let o=(0,h.useId)(),s=e.schedule.kind,c=e.schedule.timeZone??``;return(0,g.jsxs)(`fieldset`,{className:`settings-heartbeat-job`,"aria-label":`Heartbeat job ${t+1}${e.name?` (${e.name})`:``}`,children:[(0,g.jsx)(`legend`,{className:`settings-heartbeat-job-legend`,children:e.name||`Job ${t+1}`}),(0,g.jsx)(l,{id:`${o}-enabled`,label:`Enabled`,value:e.enabled,onChange:e=>i({enabled:e})}),(0,g.jsx)(d,{id:`${o}-name`,label:`Name`,value:e.name,placeholder:`Morning summary`,onChange:e=>i({name:e})}),(0,g.jsx)(u,{id:`${o}-kind`,label:`Schedule kind`,value:s,options:_,onChange:e=>{e===`every`&&s!==`every`?i({schedule:{kind:`every`,minutes:30,...c?{timeZone:c}:{}}}):e===`cron`&&s!==`cron`&&i({schedule:{kind:`cron`,cron:`0 9 * * *`,...c?{timeZone:c}:{}}})}}),s===`every`?(0,g.jsx)(d,{id:`${o}-minutes`,label:`Every (minutes)`,value:String(e.schedule.minutes??``),placeholder:`30`,error:n??null,onChange:e=>{let t=e.trim(),n=Number(t);i({schedule:{kind:`every`,minutes:Number.isFinite(n)?n:NaN,...c?{timeZone:c}:{}}})}}):(0,g.jsx)(d,{id:`${o}-cron`,label:`Cron expression`,value:e.schedule.cron??``,placeholder:`0 9 * * *`,error:n??null,onChange:e=>i({schedule:{kind:`cron`,cron:e,...c?{timeZone:c}:{}}})}),(0,g.jsx)(d,{id:`${o}-tz`,label:`Time zone (optional)`,value:c,placeholder:`Asia/Seoul`,error:r??null,onChange:t=>{let n=t.trim();i(s===`every`?{schedule:{kind:`every`,minutes:e.schedule.minutes,...n?{timeZone:n}:{}}}:{schedule:{kind:`cron`,cron:e.schedule.cron,...n?{timeZone:n}:{}}})}}),(0,g.jsxs)(`label`,{className:`settings-field settings-field-textarea`,htmlFor:`${o}-prompt`,children:[(0,g.jsx)(`span`,{className:`settings-field-label`,children:`Prompt`}),(0,g.jsx)(`textarea`,{id:`${o}-prompt`,rows:3,value:e.prompt,placeholder:`What should this heartbeat do?`,onChange:e=>i({prompt:e.target.value})})]}),(0,g.jsx)(`div`,{className:`settings-heartbeat-job-footer`,children:(0,g.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,onClick:a,children:`Remove job`})})]})}var y=/^\d+[smh]$/,b=/^([01]\d|2[0-3]):[0-5]\d$/,x=[`ai-e`,`claude`,`claude-e`,`codex`,`codex-app`,`copilot`,`cursor`,`kiro-code`,`gemini`,`grok`,`opencode`],S=[`heartbeat.enabled`,`heartbeat.every`,`heartbeat.activeHours.start`,`heartbeat.activeHours.end`,`heartbeat.target`],C=[`heartbeat.jobs`,`heartbeat.md`];function w(e){return y.test(e.trim())}function T(e){return b.test(e.trim())}var E=0;function D(e=Date.now()){return{id:`hb_${e}_${E++}`,name:``,enabled:!0,schedule:{kind:`every`,minutes:30},prompt:``}}function O(e){return e.startsWith(`heartbeat.`)&&e!==`heartbeat.jobs`&&e!==`heartbeat.md`}function k(e,t){if(!e||typeof e!=`object`)return null;let n=e,r=typeof n.id==`string`&&n.id.trim()?n.id.trim():`hb_unknown_${t}`,i=typeof n.name==`string`?n.name:``,a=n.enabled!==!1,o=typeof n.prompt==`string`?n.prompt:``,s=n.schedule,c;if(s&&typeof s==`object`){let e=s;c=e.kind===`cron`&&typeof e.cron==`string`?{kind:`cron`,cron:e.cron,...typeof e.timeZone==`string`&&e.timeZone?{timeZone:e.timeZone}:{}}:{kind:`every`,minutes:typeof e.minutes==`number`?e.minutes:30,...typeof e.timeZone==`string`&&e.timeZone?{timeZone:e.timeZone}:{}}}else c={kind:`every`,minutes:30};return{id:r,name:i,enabled:a,schedule:c,prompt:o}}function A(e){if(!e||typeof e!=`object`)return[];let t=e.jobs;return Array.isArray(t)?t.map((e,t)=>k(e,t)).filter(e=>e!==null):[]}function j(e){if(e.kind===`every`){let t=e.minutes;return!Number.isFinite(t)||t<=0||!Number.isInteger(t)?`Minutes must be a positive integer`:null}let t=e.cron?.trim()??``;return t?t.split(/\s+/).length<5?`Cron must have at least 5 fields`:null:`Cron expression required`}function M(e){return e.some(e=>j(e.schedule)!==null)}function N({port:e,client:t,dirty:n,snapshot:r}){let[i,a]=(0,h.useState)([]),[o,l]=(0,h.useState)([]),[u,d]=(0,h.useState)(!1),[f,p]=(0,h.useState)(null);(0,h.useEffect)(()=>{if(r.kind!==`ready`)return;let e=A(r.data);a(e),l(e)},[r]),(0,h.useEffect)(()=>{n.set(`heartbeat.jobs`,{value:i,original:o,valid:!M(i)})},[i,o,n]),(0,h.useEffect)(()=>()=>{n.remove(`heartbeat.jobs`)},[n]);let m=(0,h.useCallback)(async()=>{if(M(i)){p(`Fix invalid schedules before saving.`);return}d(!0),p(null);try{let e=A(await t.put(`/api/heartbeat`,{jobs:i}));a(e),l(e),n.remove(`heartbeat.jobs`)}catch(e){p(e instanceof Error?e.message:String(e))}finally{d(!1)}},[t,n,i]);if(r.kind===`loading`)return(0,g.jsx)(`p`,{className:`settings-section-hint`,children:`Loading jobs…`});if(r.kind===`offline`)return(0,g.jsx)(s,{port:e});if(r.kind===`error`)return(0,g.jsx)(c,{message:r.message});let _=n.pending.has(`heartbeat.jobs`),y=M(i);function b(e,t){a(n=>n.map((n,r)=>r===e?{...n,...t}:n))}function x(){a(e=>[...e,D()])}function S(e){a(t=>t.filter((t,n)=>n!==e))}return(0,g.jsxs)(g.Fragment,{children:[i.length===0?(0,g.jsx)(`p`,{className:`settings-section-hint`,children:`No jobs configured. Add one below.`}):(0,g.jsx)(`div`,{className:`settings-heartbeat-jobs-list`,children:i.map((e,t)=>(0,g.jsx)(v,{job:e,index:t,bodyError:j(e.schedule),onChange:e=>b(t,e),onRemove:()=>S(t)},e.id))}),(0,g.jsxs)(`div`,{className:`settings-heartbeat-jobs-footer`,children:[(0,g.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,onClick:x,children:`+ Add job`}),(0,g.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,onClick:()=>void m(),disabled:u||!_||y,children:u?`Saving…`:`Apply jobs`})]}),f?(0,g.jsx)(`p`,{className:`settings-field-error`,role:`alert`,children:f}):null]})}function P({port:e,client:t,dirty:n,snapshot:r}){let[i,a]=(0,h.useState)(``),[o,l]=(0,h.useState)(``),[u,d]=(0,h.useState)(!1),[f,p]=(0,h.useState)(null);(0,h.useEffect)(()=>{if(r.kind!==`ready`)return;let e=r.data.content??``;a(e),l(e)},[r]),(0,h.useEffect)(()=>{n.set(`heartbeat.md`,{value:i,original:o,valid:!0})},[i,o,n]),(0,h.useEffect)(()=>()=>{n.remove(`heartbeat.md`)},[n]);let m=(0,h.useCallback)(async()=>{d(!0),p(null);try{await t.put(`/api/heartbeat-md`,{content:i}),l(i),n.remove(`heartbeat.md`)}catch(e){p(e instanceof Error?e.message:String(e))}finally{d(!1)}},[t,n,i]);if(r.kind===`loading`)return(0,g.jsx)(`p`,{className:`settings-section-hint`,children:`Loading template…`});if(r.kind===`offline`)return(0,g.jsx)(s,{port:e});if(r.kind===`error`)return(0,g.jsx)(c,{message:r.message});let _=n.pending.has(`heartbeat.md`);return(0,g.jsxs)(g.Fragment,{children:[(0,g.jsxs)(`label`,{className:`settings-field settings-field-textarea`,htmlFor:`hb-md`,children:[(0,g.jsx)(`span`,{className:`settings-field-label`,children:`Template`}),(0,g.jsx)(`textarea`,{id:`hb-md`,rows:10,spellCheck:!1,value:i,onChange:e=>a(e.target.value),style:{fontFamily:`ui-monospace, monospace`}})]}),(0,g.jsx)(`div`,{className:`settings-heartbeat-md-footer`,children:(0,g.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,onClick:()=>void m(),disabled:u||!_,children:u?`Saving…`:`Save template`})}),f?(0,g.jsx)(`p`,{className:`settings-field-error`,role:`alert`,children:f}):null]})}function F({port:e,client:n,dirty:r,registerSave:_}){let v=i(n,`/api/settings`),y=i(n,`/api/heartbeat`),b=i(n,`/api/heartbeat-md`),[C,E]=(0,h.useState)(!1),[D,k]=(0,h.useState)(`30m`),[A,j]=(0,h.useState)(`08:00`),[M,F]=(0,h.useState)(`22:00`),[I,L]=(0,h.useState)(`all`);(0,h.useEffect)(()=>{if(v.state.kind!==`ready`)return;let e=v.state.data.heartbeat||{};E(!!e.enabled),k(typeof e.every==`string`?e.every:`30m`),j(e.activeHours?.start??`08:00`),F(e.activeHours?.end??`22:00`),L(typeof e.target==`string`?e.target:`all`)},[v.state]),(0,h.useEffect)(()=>()=>{for(let e of S)r.remove(e)},[r]);let R=(0,h.useMemo)(()=>v.state.kind===`ready`&&v.state.data.heartbeat||{},[v.state]),z=(0,h.useCallback)((e,t)=>r.set(e,t),[r]),B=(0,h.useRef)(0),V=(0,h.useCallback)(async()=>{let e=r.saveBundle(),t={};for(let[n,r]of Object.entries(e))O(n)&&(t[n]=r);if(Object.keys(t).length===0)return;let i=++B.current,a=m(t),o=await n.put(`/api/settings`,a);if(i!==B.current)return;let s=o&&typeof o==`object`&&`data`in o?o.data:o;for(let e of S)r.remove(e);v.setData(s);let c=s.heartbeat||{};E(!!c.enabled),k(typeof c.every==`string`?c.every:`30m`),j(c.activeHours?.start??`08:00`),F(c.activeHours?.end??`22:00`),L(typeof c.target==`string`?c.target:`all`),await v.refresh()},[n,r,v]);if((0,h.useEffect)(()=>{if(_)return _(V),()=>_(null)},[_,V]),v.state.kind===`loading`)return(0,g.jsx)(o,{});if(v.state.kind===`offline`)return(0,g.jsx)(s,{port:e});if(v.state.kind===`error`)return(0,g.jsx)(c,{message:v.state.message});let H=w(D)?null:"Use the form `<n>s|m|h`, e.g. `30m`",U=T(A)?null:`Use HH:MM (24h)`,W=T(M)?null:`Use HH:MM (24h)`,G=v.state.data.perCli||{},K=p(Object.keys(G)),q=[{value:`all`,label:`all (broadcast)`},...(K.length>0?K:[...x]).map(e=>({value:e,label:f(e).label||e}))];return!t(I)&&!q.some(e=>e.value===I)&&q.push({value:I,label:`${f(I).label||I} (legacy)`}),(0,g.jsxs)(`form`,{className:`settings-page-form`,onSubmit:e=>{e.preventDefault(),V()},children:[(0,g.jsxs)(a,{title:`Heartbeat`,hint:`Background prompts the agent runs on a schedule.`,children:[(0,g.jsx)(l,{id:`hb-enabled`,label:`Heartbeat enabled`,value:C,onChange:e=>{E(e),z(`heartbeat.enabled`,{value:e,original:!!R.enabled,valid:!0})}}),(0,g.jsx)(d,{id:`hb-every`,label:`Default interval`,value:D,placeholder:`30m`,error:H,onChange:e=>{k(e),z(`heartbeat.every`,{value:e,original:R.every??`30m`,valid:w(e)})}}),(0,g.jsx)(d,{id:`hb-start`,label:`Active hours start`,value:A,placeholder:`08:00`,error:U,onChange:e=>{j(e),z(`heartbeat.activeHours.start`,{value:e,original:R.activeHours?.start??`08:00`,valid:T(e)})}}),(0,g.jsx)(d,{id:`hb-end`,label:`Active hours end`,value:M,placeholder:`22:00`,error:W,onChange:e=>{F(e),z(`heartbeat.activeHours.end`,{value:e,original:R.activeHours?.end??`22:00`,valid:T(e)})}}),(0,g.jsx)(u,{id:`hb-target`,label:`Target`,value:I,missingValueLabel:t(I)?`JWC (retired)`:void 0,error:t(I)?`The saved target runtime is retired. Choose an available target.`:null,options:q,onChange:e=>{L(e),z(`heartbeat.target`,{value:e,original:R.target??`all`,valid:!0})}})]}),(0,g.jsx)(a,{title:`Jobs`,hint:`Each job replaces the entire heartbeat.json on save. Concurrent edits from multiple browsers will overwrite — last write wins.`,children:(0,g.jsx)(N,{port:e,client:n,dirty:r,snapshot:y.state})}),(0,g.jsx)(a,{title:`Default heartbeat prompt template`,hint:`Markdown shown to the agent when a heartbeat fires without a job-specific prompt.`,children:(0,g.jsx)(P,{port:e,client:n,dirty:r,snapshot:b.state})})]})}export{C as PAGE_LOCAL_KEYS,S as SECTION_A_KEYS,x as TARGET_FALLBACK,F as default,O as isHeartbeatSettingsKey,j as jobScheduleBodyError,M as jobsHaveErrors,D as makeDefaultJob,A as normalizeJobsResponse,T as validateHHMM,w as validateInterval};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./cli-engine-Bw0QTAVX.js";import{t as n}from"./react-C_pPTFsM.js";import{t as r}from"./jsx-runtime-NZYk81nU.js";import{a as i,i as a,n as o,r as s,t as c}from"./page-shell-BeGD0rRQ.js";import{a as l,i as u,r as d}from"./fields-mlGpofqQ.js";import{a as f,d as ee}from"./agent-meta-BWHASq1a.js";import{t as p}from"./path-utils-B6vBr0DD.js";var m=e(n(),1),h=[`memory.enabled`,`memory.flushEvery`,`memory.cli`,`memory.retentionDays`,`memory.autoReflectAfterFlush`,`memory.flushLanguage`],g=[{value:`en`,label:`English (en)`},{value:`ko`,label:`한국어 (ko)`},{value:`ja`,label:`日本語 (ja)`},{value:`zh`,label:`中文 (zh)`}],_=50;function v(e){return h.includes(e)}function y(e){let t=b(e);if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=x(e);t&&n.push(t)}return n}function b(e){if(!e||typeof e!=`object`)return e;let t=e;return Array.isArray(t)?t:`data`in t?t.data:e}function x(e){if(!e||typeof e!=`object`)return null;let t=e,n=typeof t.key==`string`?t.key:null;return n?{key:n,value:typeof t.value==`string`?t.value:``,source:typeof t.source==`string`?t.source:`manual`}:null}function S(e,t){return!Number.isFinite(e)||!Number.isInteger(e)||e<=0?`${t} must be a positive integer`:null}function C(e,t,n=50){let r=Math.max(0,Math.floor(t))*n,i=e.slice(r,r+n),a=Math.max(1,Math.ceil(e.length/n));return{slice:i,hasMore:r+n<e.length,pageCount:a}}function w(e,t=80){return e.length<=t?e:`${e.slice(0,t)}…`}var T=r();function E({row:e,onOpen:t}){return(0,T.jsxs)(`tr`,{className:`settings-memory-row`,children:[(0,T.jsx)(`td`,{className:`settings-memory-key`,children:(0,T.jsx)(`button`,{type:`button`,className:`settings-memory-link`,onClick:()=>t(e),"aria-label":`Open memory entry ${e.key}`,children:e.key})}),(0,T.jsx)(`td`,{className:`settings-memory-source`,children:e.source}),(0,T.jsx)(`td`,{className:`settings-memory-length`,children:e.value.length}),(0,T.jsx)(`td`,{className:`settings-memory-preview`,title:e.value,children:w(e.value)})]})}var D={busy:null,notice:null,error:null};function O({port:e,client:n,dirty:r,registerSave:_}){let b=i(n,`/api/settings`),x=i(n,`/api/memory`),[w,O]=(0,m.useState)(!0),[k,A]=(0,m.useState)(10),[j,M]=(0,m.useState)(``),[N,P]=(0,m.useState)(30),[F,I]=(0,m.useState)(!1),[te,L]=(0,m.useState)(`en`),[R,z]=(0,m.useState)(0),[B,V]=(0,m.useState)(null),[H,U]=(0,m.useState)(D);(0,m.useEffect)(()=>{if(b.state.kind!==`ready`)return;let e=b.state.data.memory||{};O(e.enabled!==!1),A(typeof e.flushEvery==`number`?e.flushEvery:10),M(typeof e.cli==`string`?e.cli:``),P(typeof e.retentionDays==`number`?e.retentionDays:30),I(!!e.autoReflectAfterFlush),L(typeof e.flushLanguage==`string`&&e.flushLanguage?e.flushLanguage:`en`)},[b.state]),(0,m.useEffect)(()=>()=>{for(let e of h)r.remove(e)},[r]),(0,m.useEffect)(()=>{if(!B)return;let e=e=>{e.key===`Escape`&&V(null)};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[B]);let W=(0,m.useCallback)((e,t)=>r.set(e,t),[r]),G=(0,m.useMemo)(()=>b.state.kind===`ready`&&b.state.data.memory||{},[b.state]),K=(0,m.useCallback)(async()=>{let e=r.saveBundle(),t={};for(let[n,r]of Object.entries(e))v(n)&&(t[n]=r);if(Object.keys(t).length===0)return;let i=p(t),a=await n.put(`/api/settings`,i),o=a&&typeof a==`object`&&`data`in a?a.data:a;for(let e of h)r.remove(e);b.setData(o);let s=o.memory||{};O(s.enabled!==!1),A(typeof s.flushEvery==`number`?s.flushEvery:10),M(typeof s.cli==`string`?s.cli:``),P(typeof s.retentionDays==`number`?s.retentionDays:30),I(!!s.autoReflectAfterFlush),L(typeof s.flushLanguage==`string`&&s.flushLanguage?s.flushLanguage:`en`),await b.refresh()},[n,r,b]);(0,m.useEffect)(()=>{if(_)return _(K),()=>_(null)},[_,K]);let q=(0,m.useCallback)(async()=>{U({busy:`flush`,notice:null,error:null});try{await n.post(`/api/jaw-memory/flush`,{}),U({busy:null,notice:`Memory flush queued. Browse refreshes when it completes.`,error:null}),await x.refresh()}catch(e){U({busy:null,notice:null,error:e instanceof Error?e.message:String(e)})}},[n,x]),J=(0,m.useCallback)(async()=>{U({busy:`reflect`,notice:null,error:null});try{await n.post(`/api/jaw-memory/reflect`,{}),U({busy:null,notice:`Reflect complete.`,error:null}),await x.refresh()}catch(e){U({busy:null,notice:null,error:e instanceof Error?e.message:String(e)})}},[n,x]),Y=(0,m.useCallback)(()=>{if(x.state.kind!==`ready`)return;let t=y(x.state.data),n=new Blob([JSON.stringify(t,null,2)],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`jaw-memory-${e}-${Date.now()}.json`,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)},[x.state,e]);if(b.state.kind===`loading`)return(0,T.jsx)(o,{});if(b.state.kind===`offline`)return(0,T.jsx)(s,{port:e});if(b.state.kind===`error`)return(0,T.jsx)(c,{message:b.state.message});let X=S(k,`Flush every`),Z=S(N,`Retention days`),ne=b.state.data.perCli||{},Q=[{value:``,label:`(profile default)`},...ee(Object.keys(ne)).map(e=>({value:e,label:f(e).label||e}))];j&&!t(j)&&!Q.some(e=>e.value===j)&&Q.push({value:j,label:`${f(j).label||j} (legacy)`});let $=x.state.kind===`ready`?y(x.state.data):[],{slice:re,hasMore:ie,pageCount:ae}=C($,Math.min(R,Math.max(0,Math.ceil($.length/50)-1)));return(0,T.jsxs)(`form`,{className:`settings-page-form`,onSubmit:e=>{e.preventDefault(),K()},children:[(0,T.jsxs)(a,{title:`Memory engine`,hint:`Background memory flush and reflection cadence.`,children:[(0,T.jsx)(l,{id:`memory-enabled`,label:`Memory enabled`,value:w,onChange:e=>{O(e),W(`memory.enabled`,{value:e,original:G.enabled!==!1,valid:!0})}}),(0,T.jsx)(d,{id:`memory-flush-every`,label:`Flush every (sessions)`,value:k,min:1,error:X,onChange:e=>{A(e),W(`memory.flushEvery`,{value:e,original:typeof G.flushEvery==`number`?G.flushEvery:10,valid:S(e,`Flush every`)===null})}}),(0,T.jsx)(u,{id:`memory-cli`,label:`Flush CLI`,value:j,missingValueLabel:t(j)?`JWC (retired)`:void 0,error:t(j)?`The saved runtime is retired. Choose an available runtime.`:null,options:Q,onChange:e=>{M(e),W(`memory.cli`,{value:e,original:G.cli??``,valid:!0})}}),(0,T.jsx)(d,{id:`memory-retention`,label:`Retention days`,value:N,min:1,error:Z,onChange:e=>{P(e),W(`memory.retentionDays`,{value:e,original:typeof G.retentionDays==`number`?G.retentionDays:30,valid:S(e,`Retention days`)===null})}}),(0,T.jsx)(l,{id:`memory-auto-reflect`,label:`Auto-reflect after flush`,value:F,onChange:e=>{I(e),W(`memory.autoReflectAfterFlush`,{value:e,original:!!G.autoReflectAfterFlush,valid:!0})}}),(0,T.jsx)(u,{id:`memory-flush-language`,label:`Flush language`,value:te,options:[...g],onChange:e=>{L(e),W(`memory.flushLanguage`,{value:e,original:G.flushLanguage??`en`,valid:!0})}})]}),(0,T.jsx)(a,{title:`Stored entries`,hint:`Read-only browse of the key/value memory table (50/page).`,children:x.state.kind===`loading`?(0,T.jsx)(`p`,{className:`settings-section-hint`,children:`Loading entries…`}):x.state.kind===`offline`?(0,T.jsx)(s,{port:e}):x.state.kind===`error`?(0,T.jsx)(c,{message:x.state.message}):$.length===0?(0,T.jsx)(`p`,{className:`settings-section-hint`,children:`No memory entries yet.`}):(0,T.jsxs)(T.Fragment,{children:[(0,T.jsxs)(`table`,{className:`settings-memory-table`,children:[(0,T.jsx)(`thead`,{children:(0,T.jsxs)(`tr`,{children:[(0,T.jsx)(`th`,{scope:`col`,children:`Key`}),(0,T.jsx)(`th`,{scope:`col`,children:`Source`}),(0,T.jsx)(`th`,{scope:`col`,children:`Length`}),(0,T.jsx)(`th`,{scope:`col`,children:`Preview`})]})}),(0,T.jsx)(`tbody`,{children:re.map(e=>(0,T.jsx)(E,{row:e,onOpen:V},e.key))})]}),(0,T.jsxs)(`div`,{className:`settings-memory-pagination`,children:[(0,T.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,disabled:R===0,onClick:()=>z(e=>Math.max(0,e-1)),children:`Prev`}),(0,T.jsxs)(`span`,{className:`settings-memory-pageinfo`,children:[`Page `,R+1,` / `,ae]}),(0,T.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,disabled:!ie,onClick:()=>z(e=>e+1),children:`Next`})]})]})}),(0,T.jsxs)(a,{title:`Actions`,hint:`Flush runs async — the browse list refreshes when it finishes.`,children:[(0,T.jsxs)(`div`,{className:`settings-memory-actions`,children:[(0,T.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,disabled:H.busy!==null,onClick:()=>void q(),children:H.busy===`flush`?`Queuing…`:`Flush now`}),(0,T.jsx)(`button`,{type:`button`,className:`settings-action settings-action-save`,disabled:H.busy!==null,onClick:()=>void J(),children:H.busy===`reflect`?`Reflecting…`:`Reflect soul`}),(0,T.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,disabled:x.state.kind!==`ready`,onClick:Y,children:`Export memory`})]}),H.notice?(0,T.jsx)(`p`,{className:`settings-section-hint`,role:`status`,children:H.notice}):null,H.error?(0,T.jsx)(`p`,{className:`settings-field-error`,role:`alert`,children:H.error}):null]}),B?(0,T.jsx)(`div`,{className:`settings-memory-modal`,role:`dialog`,"aria-modal":`true`,"aria-label":`Memory entry ${B.key}`,onClick:e=>{e.target===e.currentTarget&&V(null)},children:(0,T.jsxs)(`div`,{className:`settings-memory-modal-card`,children:[(0,T.jsxs)(`header`,{className:`settings-memory-modal-header`,children:[(0,T.jsx)(`h3`,{children:B.key}),(0,T.jsx)(`button`,{type:`button`,className:`settings-action settings-action-discard`,onClick:()=>V(null),"aria-label":`Close memory entry`,children:`Close`})]}),(0,T.jsx)(`pre`,{className:`settings-memory-modal-body`,children:B.value})]})}):null]})}export{g as FLUSH_LANGUAGE_OPTIONS,_ as MEMORY_PAGE_SIZE,h as MEMORY_SECTION_A_KEYS,O as default,v as isMemorySettingsKey,y as normalizeMemoryRows,C as paginate,w as previewValue,S as validatePositiveInt};
|