@codemieai/code 0.1.0 → 0.2.0
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.md +13 -0
- package/bin/codebase-memory-ui-daemon.js +10 -0
- package/bin/codemie-codex.js +18 -0
- package/dist/agents/core/AgentCLI.d.ts +1 -0
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +29 -4
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/session/sync-state-utils.d.ts +11 -0
- package/dist/agents/core/session/sync-state-utils.d.ts.map +1 -0
- package/dist/agents/core/session/sync-state-utils.js +99 -0
- package/dist/agents/core/session/sync-state-utils.js.map +1 -0
- package/dist/agents/core/session/types.d.ts +8 -0
- package/dist/agents/core/session/types.d.ts.map +1 -1
- package/dist/agents/core/session/utils/jsonl-reader.d.ts +8 -0
- package/dist/agents/core/session/utils/jsonl-reader.d.ts.map +1 -1
- package/dist/agents/core/session/utils/jsonl-reader.js +37 -0
- package/dist/agents/core/session/utils/jsonl-reader.js.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.js +1 -1
- package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/agents/plugins/claude/plugin/hooks/hooks.json +0 -15
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +2 -0
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
- package/dist/agents/plugins/codex/codex-message-types.d.ts +80 -0
- package/dist/agents/plugins/codex/codex-message-types.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex-message-types.js +36 -0
- package/dist/agents/plugins/codex/codex-message-types.js.map +1 -0
- package/dist/agents/plugins/codex/codex-models.d.ts +9 -0
- package/dist/agents/plugins/codex/codex-models.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex-models.js +227 -0
- package/dist/agents/plugins/codex/codex-models.js.map +1 -0
- package/dist/agents/plugins/codex/codex.incremental-sync.d.ts +39 -0
- package/dist/agents/plugins/codex/codex.incremental-sync.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex.incremental-sync.js +147 -0
- package/dist/agents/plugins/codex/codex.incremental-sync.js.map +1 -0
- package/dist/agents/plugins/codex/codex.paths.d.ts +29 -0
- package/dist/agents/plugins/codex/codex.paths.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex.paths.js +43 -0
- package/dist/agents/plugins/codex/codex.paths.js.map +1 -0
- package/dist/agents/plugins/codex/codex.plugin.d.ts +80 -0
- package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex.plugin.js +474 -0
- package/dist/agents/plugins/codex/codex.plugin.js.map +1 -0
- package/dist/agents/plugins/codex/codex.reconciliation.d.ts +43 -0
- package/dist/agents/plugins/codex/codex.reconciliation.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex.reconciliation.js +141 -0
- package/dist/agents/plugins/codex/codex.reconciliation.js.map +1 -0
- package/dist/agents/plugins/codex/codex.session.d.ts +58 -0
- package/dist/agents/plugins/codex/codex.session.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex.session.js +326 -0
- package/dist/agents/plugins/codex/codex.session.js.map +1 -0
- package/dist/agents/plugins/codex/codex.storage-utils.d.ts +15 -0
- package/dist/agents/plugins/codex/codex.storage-utils.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex.storage-utils.js +19 -0
- package/dist/agents/plugins/codex/codex.storage-utils.js.map +1 -0
- package/dist/agents/plugins/codex/index.d.ts +7 -0
- package/dist/agents/plugins/codex/index.d.ts.map +1 -0
- package/dist/agents/plugins/codex/index.js +9 -0
- package/dist/agents/plugins/codex/index.js.map +1 -0
- package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.d.ts +24 -0
- package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.d.ts.map +1 -0
- package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.js +613 -0
- package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.js.map +1 -0
- package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.d.ts +21 -0
- package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.d.ts.map +1 -0
- package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.js +124 -0
- package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.js.map +1 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js +1 -0
- package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode.storage-utils.js +2 -29
- package/dist/agents/plugins/opencode/opencode.storage-utils.js.map +1 -1
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map +1 -1
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +2 -0
- package/dist/agents/registry.js.map +1 -1
- package/dist/bin/codebase-memory-ui-daemon.d.ts +2 -0
- package/dist/bin/codebase-memory-ui-daemon.d.ts.map +1 -0
- package/dist/bin/codebase-memory-ui-daemon.js +141 -0
- package/dist/bin/codebase-memory-ui-daemon.js.map +1 -0
- package/dist/bin/proxy-daemon.js +4 -0
- package/dist/bin/proxy-daemon.js.map +1 -1
- package/dist/cli/commands/assistants/constants.js +2 -2
- package/dist/cli/commands/assistants/constants.js.map +1 -1
- package/dist/cli/commands/assistants/setup/configuration/constants.js +4 -4
- package/dist/cli/commands/assistants/setup/configuration/constants.js.map +1 -1
- package/dist/cli/commands/assistants/setup/configuration/ui.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/configuration/ui.js +10 -13
- package/dist/cli/commands/assistants/setup/configuration/ui.js.map +1 -1
- package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.d.ts +4 -0
- package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.d.ts.map +1 -0
- package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.js +76 -0
- package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.js.map +1 -0
- package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.d.ts +4 -0
- package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.d.ts.map +1 -0
- package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.js +68 -0
- package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.js.map +1 -0
- package/dist/cli/commands/assistants/setup/helpers.d.ts +3 -2
- package/dist/cli/commands/assistants/setup/helpers.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/helpers.js +43 -8
- package/dist/cli/commands/assistants/setup/helpers.js.map +1 -1
- package/dist/cli/commands/assistants/setup/index.d.ts +3 -1
- package/dist/cli/commands/assistants/setup/index.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/index.js +15 -12
- package/dist/cli/commands/assistants/setup/index.js.map +1 -1
- package/dist/cli/commands/assistants/setup/manualConfiguration/types.d.ts +2 -2
- package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js +2 -2
- package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js.map +1 -1
- package/dist/cli/commands/assistants/setup/selection/ui.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/selection/ui.js +8 -13
- package/dist/cli/commands/assistants/setup/selection/ui.js.map +1 -1
- package/dist/cli/commands/assistants/setup/summary/index.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/summary/index.js +14 -8
- package/dist/cli/commands/assistants/setup/summary/index.js.map +1 -1
- package/dist/cli/commands/codebase/daemon-manager.d.ts +24 -0
- package/dist/cli/commands/codebase/daemon-manager.d.ts.map +1 -0
- package/dist/cli/commands/codebase/daemon-manager.js +112 -0
- package/dist/cli/commands/codebase/daemon-manager.js.map +1 -0
- package/dist/cli/commands/codebase/index.d.ts +3 -0
- package/dist/cli/commands/codebase/index.d.ts.map +1 -0
- package/dist/cli/commands/codebase/index.js +130 -0
- package/dist/cli/commands/codebase/index.js.map +1 -0
- package/dist/cli/commands/hook.d.ts.map +1 -1
- package/dist/cli/commands/hook.js +15 -2
- package/dist/cli/commands/hook.js.map +1 -1
- package/dist/cli/commands/install.js +2 -2
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/profile/index.d.ts +14 -0
- package/dist/cli/commands/profile/index.d.ts.map +1 -1
- package/dist/cli/commands/profile/index.js +110 -27
- package/dist/cli/commands/profile/index.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop-managed-mcp-servers.json +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.d.ts +4 -6
- package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.js +92 -15
- package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
- package/dist/cli/commands/proxy/daemon-manager.d.ts +1 -0
- package/dist/cli/commands/proxy/daemon-manager.d.ts.map +1 -1
- package/dist/cli/commands/proxy/daemon-manager.js +2 -0
- package/dist/cli/commands/proxy/daemon-manager.js.map +1 -1
- package/dist/cli/commands/proxy/index.d.ts.map +1 -1
- package/dist/cli/commands/proxy/index.js +42 -0
- package/dist/cli/commands/proxy/index.js.map +1 -1
- package/dist/cli/commands/setup.js +1 -1
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/shared/agent-targets.d.ts +10 -0
- package/dist/cli/commands/shared/agent-targets.d.ts.map +1 -0
- package/dist/cli/commands/shared/agent-targets.js +220 -0
- package/dist/cli/commands/shared/agent-targets.js.map +1 -0
- package/dist/cli/commands/shared/prompts/storage-scope.d.ts.map +1 -1
- package/dist/cli/commands/shared/prompts/storage-scope.js +9 -2
- package/dist/cli/commands/shared/prompts/storage-scope.js.map +1 -1
- package/dist/cli/commands/shared/selection/ui.d.ts +22 -0
- package/dist/cli/commands/shared/selection/ui.d.ts.map +1 -1
- package/dist/cli/commands/shared/selection/ui.js +34 -0
- package/dist/cli/commands/shared/selection/ui.js.map +1 -1
- package/dist/cli/commands/skills/lib/skills-metrics.d.ts.map +1 -1
- package/dist/cli/commands/skills/lib/skills-metrics.js +47 -11
- package/dist/cli/commands/skills/lib/skills-metrics.js.map +1 -1
- package/dist/cli/commands/skills/setup/generators/codex-skill-generator.d.ts +4 -0
- package/dist/cli/commands/skills/setup/generators/codex-skill-generator.d.ts.map +1 -0
- package/dist/cli/commands/skills/setup/generators/codex-skill-generator.js +51 -0
- package/dist/cli/commands/skills/setup/generators/codex-skill-generator.js.map +1 -0
- package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.d.ts +4 -0
- package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.d.ts.map +1 -0
- package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.js +51 -0
- package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.js.map +1 -0
- package/dist/cli/commands/skills/setup/helpers.d.ts +3 -2
- package/dist/cli/commands/skills/setup/helpers.d.ts.map +1 -1
- package/dist/cli/commands/skills/setup/helpers.js +31 -6
- package/dist/cli/commands/skills/setup/helpers.js.map +1 -1
- package/dist/cli/commands/skills/setup/index.d.ts +2 -1
- package/dist/cli/commands/skills/setup/index.d.ts.map +1 -1
- package/dist/cli/commands/skills/setup/index.js +14 -11
- package/dist/cli/commands/skills/setup/index.js.map +1 -1
- package/dist/cli/commands/skills/setup/selection/ui.d.ts.map +1 -1
- package/dist/cli/commands/skills/setup/selection/ui.js +8 -13
- package/dist/cli/commands/skills/setup/selection/ui.js.map +1 -1
- package/dist/cli/commands/test-metrics.js +3 -4
- package/dist/cli/commands/test-metrics.js.map +1 -1
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/env/types.d.ts +2 -0
- package/dist/env/types.d.ts.map +1 -1
- package/dist/env/types.js.map +1 -1
- package/dist/frameworks/plugins/bmad.plugin.d.ts +10 -1
- package/dist/frameworks/plugins/bmad.plugin.d.ts.map +1 -1
- package/dist/frameworks/plugins/bmad.plugin.js +108 -9
- package/dist/frameworks/plugins/bmad.plugin.js.map +1 -1
- package/dist/frameworks/plugins/codebase-memory.plugin.d.ts +18 -0
- package/dist/frameworks/plugins/codebase-memory.plugin.d.ts.map +1 -0
- package/dist/frameworks/plugins/codebase-memory.plugin.js +131 -0
- package/dist/frameworks/plugins/codebase-memory.plugin.js.map +1 -0
- package/dist/frameworks/plugins/index.d.ts +1 -0
- package/dist/frameworks/plugins/index.d.ts.map +1 -1
- package/dist/frameworks/plugins/index.js +3 -0
- package/dist/frameworks/plugins/index.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js +4 -4
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts +20 -0
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +104 -0
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/gateway-key.plugin.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/gateway-key.plugin.js +24 -3
- package/dist/providers/plugins/sso/proxy/plugins/gateway-key.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +5 -0
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +3 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.js +5 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/logging.plugin.js +10 -3
- package/dist/providers/plugins/sso/proxy/plugins/logging.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.js +26 -8
- package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/sso.proxy.js +21 -4
- package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
- package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/SessionSyncer.js +5 -72
- package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/apiClient.d.ts +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/apiClient.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/apiClient.js +95 -4
- package/dist/providers/plugins/sso/session/processors/conversations/apiClient.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/constants.d.ts +2 -2
- package/dist/providers/plugins/sso/session/processors/conversations/constants.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/constants.js +2 -2
- package/dist/providers/plugins/sso/session/processors/conversations/constants.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +85 -21
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/types.d.ts +10 -2
- package/dist/providers/plugins/sso/session/processors/conversations/types.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js +80 -46
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts +1 -9
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js +94 -30
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts +4 -6
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js +24 -25
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js +140 -99
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts +11 -3
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.auth.js +22 -4
- package/dist/providers/plugins/sso/sso.auth.js.map +1 -1
- package/dist/providers/plugins/sso/sso.setup-steps.js +2 -2
- package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.d.ts.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.js +4 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.js.map +1 -1
- package/dist/telemetry/runtime/DesktopTelemetryRuntime.d.ts.map +1 -1
- package/dist/telemetry/runtime/DesktopTelemetryRuntime.js +1 -3
- package/dist/telemetry/runtime/DesktopTelemetryRuntime.js.map +1 -1
- package/dist/utils/browser.d.ts +7 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/browser.js +10 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +7 -1
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/paths.d.ts +8 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +15 -0
- package/dist/utils/paths.js.map +1 -1
- package/package.json +2 -1
- package/scripts/compare-codex-conversations.mjs +894 -0
- package/scripts/validate-secrets.js +7 -3
- package/dist/agents/plugins/claude/plugin/claude-templates/README.md +0 -539
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/CLAUDE.md.template +0 -252
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/code-review-agent-template.md.template +0 -433
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/refactor-cleaner-agent.md.template +0 -337
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/solution-architect-agent.md.template +0 -197
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/unit-tester-agent.md.template +0 -258
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/api/api-patterns.md.template +0 -179
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/architecture.md.template +0 -197
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/data/database-patterns.md.template +0 -248
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/development/development-practices.md.template +0 -298
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/integration/external-integrations.md.template +0 -160
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/security/security-practices.md.template +0 -295
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/code-quality.md.template +0 -186
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/git-workflow.md.template +0 -177
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/testing/testing-patterns.md.template +0 -315
- package/dist/agents/plugins/claude/plugin/commands/codemie-init.md +0 -522
- package/dist/agents/plugins/claude/plugin/commands/handoff.md +0 -56
- package/dist/agents/plugins/claude/plugin/commands/memory-refresh.md +0 -549
- package/dist/agents/plugins/claude/plugin/scripts/bash/rtk-baseline.sh +0 -39
- package/dist/agents/plugins/claude/plugin/scripts/bash/rtk-rewrite.sh +0 -101
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/SKILL.md +0 -206
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-agent.md +0 -45
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-claude-md-snippet.md +0 -40
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-command.md +0 -30
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-hooks.json +0 -23
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-skill.md +0 -48
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-agent.md +0 -145
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-claude-md-snippet.md +0 -126
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-command.md +0 -170
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-hooks.json +0 -46
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-skill.md +0 -144
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/sample-report.md +0 -223
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/references/best-practices.md +0 -510
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/references/component-checklists.md +0 -413
- package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/scripts/scan-repo.sh +0 -162
|
@@ -0,0 +1,894 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Compare raw Codex rollout transcripts against CodeMie session metadata and
|
|
5
|
+
* extracted conversation payloads.
|
|
6
|
+
*
|
|
7
|
+
* Purpose:
|
|
8
|
+
* - scan Codex rollout files under ~/.codex/sessions
|
|
9
|
+
* - find the corresponding CodeMie codex session under ~/.codemie/sessions
|
|
10
|
+
* - inspect the generated conversation payload file
|
|
11
|
+
* - highlight mismatches in key areas (matching, ids, user/assistant counts,
|
|
12
|
+
* commentary leakage, missing final answers)
|
|
13
|
+
*
|
|
14
|
+
* Notes:
|
|
15
|
+
* - Codex rollout ids are external session ids, not CodeMie session ids.
|
|
16
|
+
* - Matching first uses explicit ids, then conversation payload ids, then a
|
|
17
|
+
* cwd + time heuristic.
|
|
18
|
+
* - Conversation files are JSONL. We support a few filename variants to make
|
|
19
|
+
* investigation resilient to typos and historical naming.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { homedir } from 'os';
|
|
23
|
+
import { basename, join, resolve } from 'path';
|
|
24
|
+
import { readdir, readFile, stat } from 'fs/promises';
|
|
25
|
+
import { existsSync } from 'fs';
|
|
26
|
+
|
|
27
|
+
const DEFAULT_CODEX_HOME = join(homedir(), '.codex');
|
|
28
|
+
const DEFAULT_CODEMIE_SESSIONS = join(homedir(), '.codemie', 'sessions');
|
|
29
|
+
const DEFAULT_TIME_WINDOW_MINUTES = 180;
|
|
30
|
+
const MAX_SAMPLE_MESSAGES = 3;
|
|
31
|
+
|
|
32
|
+
function parseArgs(argv) {
|
|
33
|
+
const options = {
|
|
34
|
+
codexHome: DEFAULT_CODEX_HOME,
|
|
35
|
+
codemieSessions: DEFAULT_CODEMIE_SESSIONS,
|
|
36
|
+
sessionId: undefined,
|
|
37
|
+
limit: undefined,
|
|
38
|
+
json: false,
|
|
39
|
+
timeWindowMinutes: DEFAULT_TIME_WINDOW_MINUTES,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
43
|
+
const arg = argv[index];
|
|
44
|
+
|
|
45
|
+
if (arg === '--codex-home') {
|
|
46
|
+
options.codexHome = resolve(argv[index + 1]);
|
|
47
|
+
index += 1;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (arg === '--codemie-sessions') {
|
|
52
|
+
options.codemieSessions = resolve(argv[index + 1]);
|
|
53
|
+
index += 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (arg === '--session-id') {
|
|
58
|
+
options.sessionId = argv[index + 1];
|
|
59
|
+
index += 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (arg === '--limit') {
|
|
64
|
+
const parsed = Number.parseInt(argv[index + 1], 10);
|
|
65
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
66
|
+
options.limit = parsed;
|
|
67
|
+
}
|
|
68
|
+
index += 1;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (arg === '--time-window-minutes') {
|
|
73
|
+
const parsed = Number.parseInt(argv[index + 1], 10);
|
|
74
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
75
|
+
options.timeWindowMinutes = parsed;
|
|
76
|
+
}
|
|
77
|
+
index += 1;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (arg === '--json') {
|
|
82
|
+
options.json = true;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (arg === '--help' || arg === '-h') {
|
|
87
|
+
printHelp();
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return options;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function printHelp() {
|
|
96
|
+
console.log(`compare-codex-conversations
|
|
97
|
+
|
|
98
|
+
Usage:
|
|
99
|
+
node scripts/compare-codex-conversations.mjs [options]
|
|
100
|
+
|
|
101
|
+
Options:
|
|
102
|
+
--codex-home <path> Codex home directory (default: ~/.codex)
|
|
103
|
+
--codemie-sessions <path> CodeMie sessions directory (default: ~/.codemie/sessions)
|
|
104
|
+
--session-id <id> Only inspect a single Codex external session id
|
|
105
|
+
--limit <n> Only inspect the newest N rollout files
|
|
106
|
+
--time-window-minutes <n> Heuristic session-match window in minutes (default: 180)
|
|
107
|
+
--json Print JSON report
|
|
108
|
+
--help, -h Show help
|
|
109
|
+
`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function main() {
|
|
113
|
+
const options = parseArgs(process.argv.slice(2));
|
|
114
|
+
|
|
115
|
+
if (!existsSync(options.codexHome)) {
|
|
116
|
+
throw new Error(`Codex home does not exist: ${options.codexHome}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!existsSync(options.codemieSessions)) {
|
|
120
|
+
throw new Error(`CodeMie sessions directory does not exist: ${options.codemieSessions}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const rollouts = await collectCodexRollouts(join(options.codexHome, 'sessions'));
|
|
124
|
+
const filteredRollouts = rollouts
|
|
125
|
+
.filter((rollout) => !options.sessionId || rollout.externalSessionId === options.sessionId)
|
|
126
|
+
.sort((left, right) => right.startedAtMs - left.startedAtMs);
|
|
127
|
+
|
|
128
|
+
const rolloutSlice = options.limit ? filteredRollouts.slice(0, options.limit) : filteredRollouts;
|
|
129
|
+
const codemieSessions = await loadCodemieSessions(options.codemieSessions);
|
|
130
|
+
const report = buildReport(rolloutSlice, codemieSessions, options);
|
|
131
|
+
|
|
132
|
+
if (options.json) {
|
|
133
|
+
console.log(JSON.stringify(report, null, 2));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
printHumanReport(report, options);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function collectCodexRollouts(codexSessionsPath) {
|
|
141
|
+
if (!existsSync(codexSessionsPath)) {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const rolloutFiles = await findFilesRecursive(codexSessionsPath, (entry) =>
|
|
146
|
+
entry.isFile() && entry.name.startsWith('rollout-') && entry.name.endsWith('.jsonl')
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const results = [];
|
|
150
|
+
|
|
151
|
+
for (const filePath of rolloutFiles) {
|
|
152
|
+
const analysis = await analyzeCodexRollout(filePath);
|
|
153
|
+
if (analysis) {
|
|
154
|
+
results.push(analysis);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return results;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function analyzeCodexRollout(filePath) {
|
|
162
|
+
const lines = await readJsonlTolerant(filePath);
|
|
163
|
+
if (lines.length === 0) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let sessionMeta;
|
|
168
|
+
let lastTurnContext;
|
|
169
|
+
|
|
170
|
+
const eventUsers = [];
|
|
171
|
+
const responseUsers = [];
|
|
172
|
+
const assistantCommentary = [];
|
|
173
|
+
const assistantFinal = [];
|
|
174
|
+
const assistantOther = [];
|
|
175
|
+
|
|
176
|
+
for (const [index, record] of lines.entries()) {
|
|
177
|
+
if (record?.type === 'session_meta') {
|
|
178
|
+
sessionMeta = record.payload;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (record?.type === 'turn_context') {
|
|
183
|
+
lastTurnContext = record.payload;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (record?.type === 'event_msg') {
|
|
188
|
+
const payload = record.payload ?? {};
|
|
189
|
+
if (payload.type === 'user_message' && typeof payload.message === 'string' && payload.message.trim()) {
|
|
190
|
+
eventUsers.push(createMessageSummary({
|
|
191
|
+
text: payload.message,
|
|
192
|
+
timestamp: record.timestamp ?? sessionMeta?.timestamp,
|
|
193
|
+
sourceIndex: index,
|
|
194
|
+
sourceType: 'event_user_message',
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (record?.type !== 'response_item') {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const payload = record.payload ?? {};
|
|
205
|
+
if (payload.type !== 'message') {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const role = typeof payload.role === 'string' ? payload.role : undefined;
|
|
210
|
+
const phase = typeof payload.phase === 'string' ? payload.phase : undefined;
|
|
211
|
+
const text = extractCodexText(payload.content ?? payload.output);
|
|
212
|
+
if (!text) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const summary = createMessageSummary({
|
|
217
|
+
text,
|
|
218
|
+
timestamp: record.timestamp ?? sessionMeta?.timestamp,
|
|
219
|
+
sourceIndex: index,
|
|
220
|
+
sourceType: `response_${role ?? 'unknown'}_${phase ?? 'none'}`,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
if (role === 'user') {
|
|
224
|
+
responseUsers.push(summary);
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (role === 'assistant' && phase === 'final_answer') {
|
|
229
|
+
assistantFinal.push(summary);
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (role === 'assistant' && phase === 'commentary') {
|
|
234
|
+
assistantCommentary.push(summary);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (role === 'assistant') {
|
|
239
|
+
assistantOther.push(summary);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (!sessionMeta?.id) {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const fileStats = await stat(filePath);
|
|
248
|
+
const startedAtMs = toTimestampMs(sessionMeta.timestamp) ?? fileStats.mtimeMs;
|
|
249
|
+
const expectedUsers = dedupeMessages([...eventUsers, ...responseUsers]);
|
|
250
|
+
const model = stringOrUndefined(lastTurnContext?.model) ?? stringOrUndefined(sessionMeta.model_provider);
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
filePath,
|
|
254
|
+
fileName: basename(filePath),
|
|
255
|
+
externalSessionId: sessionMeta.id,
|
|
256
|
+
startedAtMs,
|
|
257
|
+
metadata: {
|
|
258
|
+
cwd: stringOrUndefined(sessionMeta.cwd),
|
|
259
|
+
timestamp: stringOrUndefined(sessionMeta.timestamp),
|
|
260
|
+
cliVersion: stringOrUndefined(sessionMeta.cli_version),
|
|
261
|
+
model,
|
|
262
|
+
},
|
|
263
|
+
counts: {
|
|
264
|
+
rawRecords: lines.length,
|
|
265
|
+
eventUsers: eventUsers.length,
|
|
266
|
+
responseUsers: responseUsers.length,
|
|
267
|
+
expectedUsers: expectedUsers.length,
|
|
268
|
+
assistantFinal: assistantFinal.length,
|
|
269
|
+
assistantCommentary: assistantCommentary.length,
|
|
270
|
+
assistantOther: assistantOther.length,
|
|
271
|
+
},
|
|
272
|
+
messages: {
|
|
273
|
+
eventUsers,
|
|
274
|
+
responseUsers,
|
|
275
|
+
expectedUsers,
|
|
276
|
+
assistantFinal,
|
|
277
|
+
assistantCommentary,
|
|
278
|
+
assistantOther,
|
|
279
|
+
},
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async function loadCodemieSessions(codemieSessionsPath) {
|
|
284
|
+
const entries = await readdir(codemieSessionsPath);
|
|
285
|
+
const sessions = [];
|
|
286
|
+
|
|
287
|
+
for (const entry of entries) {
|
|
288
|
+
if (!entry.endsWith('.json')) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const filePath = join(codemieSessionsPath, entry);
|
|
293
|
+
let parsed;
|
|
294
|
+
try {
|
|
295
|
+
parsed = JSON.parse(await readFile(filePath, 'utf-8'));
|
|
296
|
+
} catch {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (parsed?.agentName !== 'codex') {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const baseName = entry.slice(0, -'.json'.length);
|
|
305
|
+
const conversationFile = await findConversationFile(codemieSessionsPath, baseName);
|
|
306
|
+
const conversationAnalysis = conversationFile
|
|
307
|
+
? await analyzeCodemieConversationFile(conversationFile)
|
|
308
|
+
: null;
|
|
309
|
+
|
|
310
|
+
sessions.push({
|
|
311
|
+
filePath,
|
|
312
|
+
fileName: entry,
|
|
313
|
+
baseName,
|
|
314
|
+
sessionId: parsed.sessionId,
|
|
315
|
+
raw: parsed,
|
|
316
|
+
startedAtMs: typeof parsed.startTime === 'number' ? parsed.startTime : undefined,
|
|
317
|
+
matchKeys: collectCodemieMatchKeys(parsed, conversationAnalysis),
|
|
318
|
+
conversationFile,
|
|
319
|
+
conversationAnalysis,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return sessions;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function findConversationFile(dirPath, baseName) {
|
|
327
|
+
const candidates = [
|
|
328
|
+
`${baseName}_conversation.jsonl`,
|
|
329
|
+
`${baseName}_conversations.jsonl`,
|
|
330
|
+
`${baseName}_conversations.json`,
|
|
331
|
+
`${baseName}_converations.jsonl`,
|
|
332
|
+
`${baseName}_converations.json`,
|
|
333
|
+
];
|
|
334
|
+
|
|
335
|
+
for (const candidate of candidates) {
|
|
336
|
+
const fullPath = join(dirPath, candidate);
|
|
337
|
+
if (existsSync(fullPath)) {
|
|
338
|
+
return fullPath;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function analyzeCodemieConversationFile(filePath) {
|
|
346
|
+
const records = await readJsonlTolerant(filePath);
|
|
347
|
+
const historyEntries = [];
|
|
348
|
+
const payloadConversationIds = new Set();
|
|
349
|
+
const lastProcessedSourceIndices = [];
|
|
350
|
+
|
|
351
|
+
for (const record of records) {
|
|
352
|
+
const conversationId = record?.payload?.conversationId;
|
|
353
|
+
if (typeof conversationId === 'string' && conversationId.trim()) {
|
|
354
|
+
payloadConversationIds.add(conversationId);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const history = Array.isArray(record?.payload?.history) ? record.payload.history : [];
|
|
358
|
+
for (const entry of history) {
|
|
359
|
+
if (!entry || typeof entry !== 'object') {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
const role = typeof entry.role === 'string' ? entry.role : undefined;
|
|
363
|
+
const message = typeof entry.message === 'string' ? entry.message : undefined;
|
|
364
|
+
if (!role || !message || !message.trim()) {
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
historyEntries.push(createMessageSummary({
|
|
369
|
+
text: message,
|
|
370
|
+
timestamp: typeof entry.date === 'string' ? entry.date : undefined,
|
|
371
|
+
sourceIndex: typeof entry.history_index === 'number' ? entry.history_index : undefined,
|
|
372
|
+
sourceType: role,
|
|
373
|
+
}));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const lastProcessed = typeof record?.lastProcessedMessageUuid === 'string'
|
|
377
|
+
? record.lastProcessedMessageUuid
|
|
378
|
+
: undefined;
|
|
379
|
+
const parsedIndex = parseTrailingSourceIndex(lastProcessed);
|
|
380
|
+
if (parsedIndex !== undefined) {
|
|
381
|
+
lastProcessedSourceIndices.push(parsedIndex);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const userEntries = dedupeMessages(historyEntries.filter((entry) => entry.sourceType === 'User'));
|
|
386
|
+
const assistantEntries = dedupeMessages(historyEntries.filter((entry) => entry.sourceType === 'Assistant'));
|
|
387
|
+
|
|
388
|
+
return {
|
|
389
|
+
filePath,
|
|
390
|
+
payloadCount: records.length,
|
|
391
|
+
payloadConversationIds: [...payloadConversationIds],
|
|
392
|
+
maxLastProcessedSourceIndex: lastProcessedSourceIndices.length > 0
|
|
393
|
+
? Math.max(...lastProcessedSourceIndices)
|
|
394
|
+
: undefined,
|
|
395
|
+
counts: {
|
|
396
|
+
historyEntries: historyEntries.length,
|
|
397
|
+
userEntries: userEntries.length,
|
|
398
|
+
assistantEntries: assistantEntries.length,
|
|
399
|
+
},
|
|
400
|
+
messages: {
|
|
401
|
+
userEntries,
|
|
402
|
+
assistantEntries,
|
|
403
|
+
},
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function collectCodemieMatchKeys(session, conversationAnalysis) {
|
|
408
|
+
const keys = new Set();
|
|
409
|
+
|
|
410
|
+
const correlationAgentSessionId = session?.correlation?.agentSessionId;
|
|
411
|
+
const runtimeExternalId = session?.runtimeCheckpoint?.externalSessionId;
|
|
412
|
+
const syncConversationId = session?.sync?.conversations?.conversationId;
|
|
413
|
+
|
|
414
|
+
for (const value of [
|
|
415
|
+
correlationAgentSessionId,
|
|
416
|
+
runtimeExternalId,
|
|
417
|
+
syncConversationId,
|
|
418
|
+
...(conversationAnalysis?.payloadConversationIds ?? []),
|
|
419
|
+
]) {
|
|
420
|
+
if (typeof value === 'string' && value.trim() && value !== 'unknown') {
|
|
421
|
+
keys.add(value);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return [...keys];
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function buildReport(rollouts, codemieSessions, options) {
|
|
429
|
+
const comparisons = rollouts.map((rollout) =>
|
|
430
|
+
compareRolloutToCodemie(rollout, codemieSessions, options)
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
const summary = {
|
|
434
|
+
rolloutCount: comparisons.length,
|
|
435
|
+
matchedCount: comparisons.filter((item) => item.match.found).length,
|
|
436
|
+
unmatchedCount: comparisons.filter((item) => !item.match.found).length,
|
|
437
|
+
missingConversationFileCount: comparisons.filter((item) =>
|
|
438
|
+
item.match.found && !item.codemie?.conversation?.exists
|
|
439
|
+
).length,
|
|
440
|
+
conversationIdMismatchCount: comparisons.filter((item) =>
|
|
441
|
+
item.comparison.problems.some((problem) => problem.code === 'conversation_id_mismatch')
|
|
442
|
+
).length,
|
|
443
|
+
commentaryLeakCount: comparisons.filter((item) =>
|
|
444
|
+
item.comparison.problems.some((problem) => problem.code === 'assistant_commentary_leak')
|
|
445
|
+
).length,
|
|
446
|
+
missingFinalAnswerCount: comparisons.filter((item) =>
|
|
447
|
+
item.comparison.problems.some((problem) => problem.code === 'missing_final_answers')
|
|
448
|
+
).length,
|
|
449
|
+
missingUserMessageCount: comparisons.filter((item) =>
|
|
450
|
+
item.comparison.problems.some((problem) => problem.code === 'missing_user_messages')
|
|
451
|
+
).length,
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
return {
|
|
455
|
+
scannedAt: new Date().toISOString(),
|
|
456
|
+
options,
|
|
457
|
+
summary,
|
|
458
|
+
comparisons,
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function compareRolloutToCodemie(rollout, codemieSessions, options) {
|
|
463
|
+
const matched = findBestCodemieMatch(rollout, codemieSessions, options.timeWindowMinutes);
|
|
464
|
+
const codemie = matched?.session;
|
|
465
|
+
|
|
466
|
+
const comparison = {
|
|
467
|
+
problems: [],
|
|
468
|
+
overlaps: undefined,
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
if (!codemie) {
|
|
472
|
+
comparison.problems.push({
|
|
473
|
+
code: 'no_codemie_session_match',
|
|
474
|
+
message: 'No matching CodeMie codex session was found',
|
|
475
|
+
});
|
|
476
|
+
} else if (!codemie.conversationAnalysis) {
|
|
477
|
+
comparison.problems.push({
|
|
478
|
+
code: 'missing_conversation_file',
|
|
479
|
+
message: 'CodeMie session exists, but no conversation payload file was found',
|
|
480
|
+
});
|
|
481
|
+
} else {
|
|
482
|
+
const extracted = codemie.conversationAnalysis;
|
|
483
|
+
const sourceUsers = rollout.messages.expectedUsers;
|
|
484
|
+
const sourceFinal = rollout.messages.assistantFinal;
|
|
485
|
+
const sourceCommentary = rollout.messages.assistantCommentary;
|
|
486
|
+
const extractedUsers = extracted.messages.userEntries;
|
|
487
|
+
const extractedAssistant = extracted.messages.assistantEntries;
|
|
488
|
+
|
|
489
|
+
const overlap = {
|
|
490
|
+
sourceUsers: compareMessageSets(sourceUsers, extractedUsers),
|
|
491
|
+
sourceFinalAnswers: compareMessageSets(sourceFinal, extractedAssistant),
|
|
492
|
+
sourceCommentaryVsExtractedAssistant: compareMessageSets(sourceCommentary, extractedAssistant),
|
|
493
|
+
};
|
|
494
|
+
comparison.overlaps = overlap;
|
|
495
|
+
|
|
496
|
+
if (sourceUsers.length > extractedUsers.length || overlap.sourceUsers.missing.length > 0) {
|
|
497
|
+
comparison.problems.push({
|
|
498
|
+
code: 'missing_user_messages',
|
|
499
|
+
message: 'Extracted conversation is missing user messages from the rollout',
|
|
500
|
+
details: {
|
|
501
|
+
sourceUsers: sourceUsers.length,
|
|
502
|
+
extractedUsers: extractedUsers.length,
|
|
503
|
+
missingExamples: overlap.sourceUsers.missing.slice(0, MAX_SAMPLE_MESSAGES),
|
|
504
|
+
},
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (sourceFinal.length > extractedAssistant.length || overlap.sourceFinalAnswers.missing.length > 0) {
|
|
509
|
+
comparison.problems.push({
|
|
510
|
+
code: 'missing_final_answers',
|
|
511
|
+
message: 'Extracted conversation is missing assistant final answers from the rollout',
|
|
512
|
+
details: {
|
|
513
|
+
sourceFinalAnswers: sourceFinal.length,
|
|
514
|
+
extractedAssistant: extractedAssistant.length,
|
|
515
|
+
missingExamples: overlap.sourceFinalAnswers.missing.slice(0, MAX_SAMPLE_MESSAGES),
|
|
516
|
+
},
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (overlap.sourceCommentaryVsExtractedAssistant.matched.length > 0) {
|
|
521
|
+
comparison.problems.push({
|
|
522
|
+
code: 'assistant_commentary_leak',
|
|
523
|
+
message: 'Commentary assistant messages were extracted into the conversation payload',
|
|
524
|
+
details: {
|
|
525
|
+
leakedCount: overlap.sourceCommentaryVsExtractedAssistant.matched.length,
|
|
526
|
+
leakedExamples: overlap.sourceCommentaryVsExtractedAssistant.matched.slice(0, MAX_SAMPLE_MESSAGES),
|
|
527
|
+
},
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const extractedConversationIds = extracted.payloadConversationIds;
|
|
532
|
+
if (
|
|
533
|
+
extractedConversationIds.length > 0 &&
|
|
534
|
+
!extractedConversationIds.includes(rollout.externalSessionId)
|
|
535
|
+
) {
|
|
536
|
+
comparison.problems.push({
|
|
537
|
+
code: 'conversation_id_mismatch',
|
|
538
|
+
message: 'Conversation payload ids do not contain the Codex rollout session id',
|
|
539
|
+
details: {
|
|
540
|
+
codexExternalSessionId: rollout.externalSessionId,
|
|
541
|
+
payloadConversationIds: extractedConversationIds,
|
|
542
|
+
},
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (extractedConversationIds.length > 1) {
|
|
547
|
+
comparison.problems.push({
|
|
548
|
+
code: 'multiple_conversation_ids',
|
|
549
|
+
message: 'Conversation payload file contains multiple conversation ids for one CodeMie session',
|
|
550
|
+
details: {
|
|
551
|
+
payloadConversationIds: extractedConversationIds,
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return {
|
|
558
|
+
codex: {
|
|
559
|
+
externalSessionId: rollout.externalSessionId,
|
|
560
|
+
filePath: rollout.filePath,
|
|
561
|
+
metadata: rollout.metadata,
|
|
562
|
+
counts: rollout.counts,
|
|
563
|
+
samples: {
|
|
564
|
+
expectedUsers: sampleMessages(rollout.messages.expectedUsers),
|
|
565
|
+
assistantFinal: sampleMessages(rollout.messages.assistantFinal),
|
|
566
|
+
assistantCommentary: sampleMessages(rollout.messages.assistantCommentary),
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
match: matched
|
|
570
|
+
? {
|
|
571
|
+
found: true,
|
|
572
|
+
method: matched.method,
|
|
573
|
+
score: matched.score,
|
|
574
|
+
timeDeltaMs: matched.timeDeltaMs,
|
|
575
|
+
}
|
|
576
|
+
: {
|
|
577
|
+
found: false,
|
|
578
|
+
},
|
|
579
|
+
codemie: codemie
|
|
580
|
+
? {
|
|
581
|
+
sessionId: codemie.sessionId,
|
|
582
|
+
filePath: codemie.filePath,
|
|
583
|
+
status: codemie.raw?.status,
|
|
584
|
+
workingDirectory: codemie.raw?.workingDirectory,
|
|
585
|
+
correlationAgentSessionId: codemie.raw?.correlation?.agentSessionId,
|
|
586
|
+
syncConversationId: codemie.raw?.sync?.conversations?.conversationId,
|
|
587
|
+
conversation: codemie.conversationAnalysis
|
|
588
|
+
? {
|
|
589
|
+
exists: true,
|
|
590
|
+
filePath: codemie.conversationFile,
|
|
591
|
+
payloadConversationIds: codemie.conversationAnalysis.payloadConversationIds,
|
|
592
|
+
counts: codemie.conversationAnalysis.counts,
|
|
593
|
+
samples: {
|
|
594
|
+
userEntries: sampleMessages(codemie.conversationAnalysis.messages.userEntries),
|
|
595
|
+
assistantEntries: sampleMessages(codemie.conversationAnalysis.messages.assistantEntries),
|
|
596
|
+
},
|
|
597
|
+
}
|
|
598
|
+
: {
|
|
599
|
+
exists: false,
|
|
600
|
+
},
|
|
601
|
+
}
|
|
602
|
+
: null,
|
|
603
|
+
comparison,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
function findBestCodemieMatch(rollout, codemieSessions, timeWindowMinutes) {
|
|
608
|
+
const explicitMatches = codemieSessions
|
|
609
|
+
.filter((session) => session.matchKeys.includes(rollout.externalSessionId))
|
|
610
|
+
.map((session) => ({
|
|
611
|
+
session,
|
|
612
|
+
method: 'explicit_id',
|
|
613
|
+
score: 100,
|
|
614
|
+
timeDeltaMs: absoluteTimeDelta(rollout.startedAtMs, session.startedAtMs),
|
|
615
|
+
}));
|
|
616
|
+
|
|
617
|
+
if (explicitMatches.length > 0) {
|
|
618
|
+
return explicitMatches.sort(compareMatches)[0];
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
const maxTimeDeltaMs = timeWindowMinutes * 60 * 1000;
|
|
622
|
+
const heuristicMatches = codemieSessions
|
|
623
|
+
.filter((session) => session.raw?.workingDirectory === rollout.metadata.cwd)
|
|
624
|
+
.map((session) => ({
|
|
625
|
+
session,
|
|
626
|
+
method: 'cwd_and_time',
|
|
627
|
+
score: scoreHeuristicMatch(rollout, session, maxTimeDeltaMs),
|
|
628
|
+
timeDeltaMs: absoluteTimeDelta(rollout.startedAtMs, session.startedAtMs),
|
|
629
|
+
}))
|
|
630
|
+
.filter((match) => match.score > 0);
|
|
631
|
+
|
|
632
|
+
if (heuristicMatches.length > 0) {
|
|
633
|
+
return heuristicMatches.sort(compareMatches)[0];
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function scoreHeuristicMatch(rollout, session, maxTimeDeltaMs) {
|
|
640
|
+
const timeDeltaMs = absoluteTimeDelta(rollout.startedAtMs, session.startedAtMs);
|
|
641
|
+
if (timeDeltaMs === undefined || timeDeltaMs > maxTimeDeltaMs) {
|
|
642
|
+
return 0;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
const branchMatches =
|
|
646
|
+
stringOrUndefined(session.raw?.gitBranch) &&
|
|
647
|
+
stringOrUndefined(session.raw?.gitBranch) === stringOrUndefined(rollout.metadata.branch);
|
|
648
|
+
|
|
649
|
+
const timeScore = Math.max(1, 60 - Math.floor(timeDeltaMs / 60000));
|
|
650
|
+
return timeScore + (branchMatches ? 10 : 0);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
function compareMatches(left, right) {
|
|
654
|
+
if (right.score !== left.score) {
|
|
655
|
+
return right.score - left.score;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
const leftDelta = left.timeDeltaMs ?? Number.MAX_SAFE_INTEGER;
|
|
659
|
+
const rightDelta = right.timeDeltaMs ?? Number.MAX_SAFE_INTEGER;
|
|
660
|
+
return leftDelta - rightDelta;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function compareMessageSets(sourceMessages, targetMessages) {
|
|
664
|
+
const targetPool = targetMessages.map((message) => normalizeText(message.text));
|
|
665
|
+
const matched = [];
|
|
666
|
+
const missing = [];
|
|
667
|
+
|
|
668
|
+
for (const message of sourceMessages) {
|
|
669
|
+
const normalized = normalizeText(message.text);
|
|
670
|
+
const foundIndex = targetPool.indexOf(normalized);
|
|
671
|
+
if (foundIndex >= 0) {
|
|
672
|
+
matched.push(sampleMessage(message));
|
|
673
|
+
targetPool.splice(foundIndex, 1);
|
|
674
|
+
} else {
|
|
675
|
+
missing.push(sampleMessage(message));
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
return {
|
|
680
|
+
matched,
|
|
681
|
+
missing,
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function createMessageSummary({ text, timestamp, sourceIndex, sourceType }) {
|
|
686
|
+
return {
|
|
687
|
+
text,
|
|
688
|
+
timestamp: typeof timestamp === 'string' ? timestamp : undefined,
|
|
689
|
+
sourceIndex,
|
|
690
|
+
sourceType,
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
function sampleMessages(messages) {
|
|
695
|
+
return messages.slice(0, MAX_SAMPLE_MESSAGES).map(sampleMessage);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
function sampleMessage(message) {
|
|
699
|
+
return {
|
|
700
|
+
text: shorten(message.text, 200),
|
|
701
|
+
timestamp: message.timestamp,
|
|
702
|
+
sourceIndex: message.sourceIndex,
|
|
703
|
+
sourceType: message.sourceType,
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function dedupeMessages(messages) {
|
|
708
|
+
const seen = new Set();
|
|
709
|
+
const deduped = [];
|
|
710
|
+
|
|
711
|
+
for (const message of messages) {
|
|
712
|
+
const key = `${message.sourceType}|${message.sourceIndex ?? ''}|${normalizeText(message.text)}`;
|
|
713
|
+
if (seen.has(key)) {
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
seen.add(key);
|
|
717
|
+
deduped.push(message);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return deduped;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function extractCodexText(content) {
|
|
724
|
+
if (typeof content === 'string' && content.trim()) {
|
|
725
|
+
return content;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
if (Array.isArray(content)) {
|
|
729
|
+
const parts = content
|
|
730
|
+
.map((item) => {
|
|
731
|
+
if (typeof item === 'string') {
|
|
732
|
+
return item;
|
|
733
|
+
}
|
|
734
|
+
if (item && typeof item === 'object' && typeof item.text === 'string') {
|
|
735
|
+
return item.text;
|
|
736
|
+
}
|
|
737
|
+
return undefined;
|
|
738
|
+
})
|
|
739
|
+
.filter((item) => typeof item === 'string' && item.trim());
|
|
740
|
+
|
|
741
|
+
return parts.length > 0 ? parts.join('\n') : undefined;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
if (content && typeof content === 'object' && typeof content.text === 'string' && content.text.trim()) {
|
|
745
|
+
return content.text;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
return undefined;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
function normalizeText(value) {
|
|
752
|
+
return value.replace(/\s+/g, ' ').trim();
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
function shorten(value, maxLength) {
|
|
756
|
+
if (value.length <= maxLength) {
|
|
757
|
+
return value;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
return `${value.slice(0, maxLength - 1)}…`;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
function parseTrailingSourceIndex(value) {
|
|
764
|
+
if (typeof value !== 'string') {
|
|
765
|
+
return undefined;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
const index = Number.parseInt(value.slice(value.lastIndexOf('@') + 1), 10);
|
|
769
|
+
return Number.isFinite(index) ? index : undefined;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
function stringOrUndefined(value) {
|
|
773
|
+
return typeof value === 'string' && value.trim() ? value : undefined;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
function toTimestampMs(value) {
|
|
777
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
778
|
+
return value;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
if (typeof value === 'string') {
|
|
782
|
+
const timestamp = new Date(value).getTime();
|
|
783
|
+
return Number.isNaN(timestamp) ? undefined : timestamp;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
return undefined;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
function absoluteTimeDelta(left, right) {
|
|
790
|
+
if (!Number.isFinite(left) || !Number.isFinite(right)) {
|
|
791
|
+
return undefined;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
return Math.abs(left - right);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
async function readJsonlTolerant(filePath) {
|
|
798
|
+
const content = await readFile(filePath, 'utf-8');
|
|
799
|
+
const lines = [];
|
|
800
|
+
|
|
801
|
+
for (const line of content.split('\n')) {
|
|
802
|
+
if (!line.trim()) {
|
|
803
|
+
continue;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
try {
|
|
807
|
+
lines.push(JSON.parse(line));
|
|
808
|
+
} catch {
|
|
809
|
+
// Ignore malformed lines during investigation.
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
return lines;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
async function findFilesRecursive(rootPath, include) {
|
|
817
|
+
const results = [];
|
|
818
|
+
const entries = await readdir(rootPath, { withFileTypes: true });
|
|
819
|
+
|
|
820
|
+
for (const entry of entries) {
|
|
821
|
+
const entryPath = join(rootPath, entry.name);
|
|
822
|
+
if (entry.isDirectory()) {
|
|
823
|
+
results.push(...await findFilesRecursive(entryPath, include));
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
if (include(entry)) {
|
|
828
|
+
results.push(entryPath);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
return results;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
function printHumanReport(report, options) {
|
|
836
|
+
const { summary, comparisons } = report;
|
|
837
|
+
|
|
838
|
+
console.log('Codex conversation comparison');
|
|
839
|
+
console.log(`- scanned at: ${report.scannedAt}`);
|
|
840
|
+
console.log(`- codex home: ${options.codexHome}`);
|
|
841
|
+
console.log(`- codemie sessions: ${options.codemieSessions}`);
|
|
842
|
+
console.log(`- rollout files scanned: ${summary.rolloutCount}`);
|
|
843
|
+
console.log(`- matched sessions: ${summary.matchedCount}`);
|
|
844
|
+
console.log(`- unmatched sessions: ${summary.unmatchedCount}`);
|
|
845
|
+
console.log(`- missing conversation files: ${summary.missingConversationFileCount}`);
|
|
846
|
+
console.log(`- conversation id mismatches: ${summary.conversationIdMismatchCount}`);
|
|
847
|
+
console.log(`- commentary leaks: ${summary.commentaryLeakCount}`);
|
|
848
|
+
console.log(`- missing final answers: ${summary.missingFinalAnswerCount}`);
|
|
849
|
+
console.log(`- missing user messages: ${summary.missingUserMessageCount}`);
|
|
850
|
+
|
|
851
|
+
const problematic = comparisons.filter((item) => item.comparison.problems.length > 0);
|
|
852
|
+
if (problematic.length === 0) {
|
|
853
|
+
console.log('\nNo obvious mismatches found.');
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
console.log(`\nProblem sessions (${problematic.length}):`);
|
|
858
|
+
|
|
859
|
+
for (const item of problematic) {
|
|
860
|
+
console.log(`\n- codex session: ${item.codex.externalSessionId}`);
|
|
861
|
+
console.log(` rollout: ${item.codex.filePath}`);
|
|
862
|
+
console.log(` match: ${item.match.found ? `${item.match.method} (score=${item.match.score})` : 'none'}`);
|
|
863
|
+
|
|
864
|
+
if (item.codemie) {
|
|
865
|
+
console.log(` codemie session: ${item.codemie.sessionId}`);
|
|
866
|
+
console.log(` status: ${item.codemie.status}`);
|
|
867
|
+
console.log(` conversation file: ${item.codemie.conversation.exists ? item.codemie.conversation.filePath : 'missing'}`);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
console.log(` source counts: users=${item.codex.counts.expectedUsers} finals=${item.codex.counts.assistantFinal} commentary=${item.codex.counts.assistantCommentary}`);
|
|
871
|
+
|
|
872
|
+
if (item.codemie?.conversation?.exists) {
|
|
873
|
+
console.log(` extracted counts: users=${item.codemie.conversation.counts.userEntries} assistant=${item.codemie.conversation.counts.assistantEntries}`);
|
|
874
|
+
if (item.codemie.conversation.payloadConversationIds.length > 0) {
|
|
875
|
+
console.log(` payload ids: ${item.codemie.conversation.payloadConversationIds.join(', ')}`);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
for (const problem of item.comparison.problems) {
|
|
880
|
+
console.log(` * ${problem.code}: ${problem.message}`);
|
|
881
|
+
if (problem.details?.missingExamples?.length > 0) {
|
|
882
|
+
console.log(` missing examples: ${problem.details.missingExamples.map((entry) => JSON.stringify(entry.text)).join(' | ')}`);
|
|
883
|
+
}
|
|
884
|
+
if (problem.details?.leakedExamples?.length > 0) {
|
|
885
|
+
console.log(` leaked examples: ${problem.details.leakedExamples.map((entry) => JSON.stringify(entry.text)).join(' | ')}`);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
await main().catch((error) => {
|
|
892
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
893
|
+
process.exit(1);
|
|
894
|
+
});
|