@gajae-code/coding-agent 0.14.2 → 0.15.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/CHANGELOG.md +120 -1
- package/dist/types/async/job-manager.d.ts +4 -1
- package/dist/types/autoresearch/dashboard.d.ts +29 -4
- package/dist/types/autoresearch/data-context.d.ts +25 -0
- package/dist/types/autoresearch/git.d.ts +65 -7
- package/dist/types/autoresearch/harness.d.ts +58 -0
- package/dist/types/autoresearch/prompts.d.ts +51 -0
- package/dist/types/autoresearch/runs.d.ts +173 -0
- package/dist/types/autoresearch/types.d.ts +9 -139
- package/dist/types/capability/types.d.ts +20 -0
- package/dist/types/cli/accounts-cli.d.ts +1 -0
- package/dist/types/commands/{rlm.d.ts → autoresearch.d.ts} +2 -4
- package/dist/types/config/autorouting-contract.d.ts +146 -0
- package/dist/types/config/autorouting-generator.d.ts +40 -0
- package/dist/types/config/autorouting-tier-map.d.ts +16844 -0
- package/dist/types/config/autorouting.d.ts +35 -0
- package/dist/types/config/model-discovery-manager.d.ts +8 -1
- package/dist/types/config/model-registry.d.ts +30 -1
- package/dist/types/config/provider-selection-policy.d.ts +23 -0
- package/dist/types/config/settings-schema.d.ts +61 -3
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/coordinator/contract.d.ts +1 -1
- package/dist/types/coordinator-mcp/durability.d.ts +29 -0
- package/dist/types/coordinator-mcp/event-webhook.d.ts +50 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +1 -1
- package/dist/types/coordinator-mcp/server.d.ts +14 -0
- package/dist/types/crash/index-store.d.ts +3 -0
- package/dist/types/crash/record-loader.d.ts +2 -0
- package/dist/types/crash/upstream/relay.d.ts +5 -3
- package/dist/types/cursor.d.ts +12 -0
- package/dist/types/defaults/gjc-defaults.d.ts +35 -1
- package/dist/types/defaults/gjc-skills.generated.d.ts +1 -1
- package/dist/types/discovery/helpers.d.ts +1 -1
- package/dist/types/edit/index.d.ts +2 -1
- package/dist/types/eval/py/executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/loader.d.ts +32 -0
- package/dist/types/extensibility/gjc-plugins/types.d.ts +1 -1
- package/dist/types/extensibility/skills.d.ts +2 -0
- package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +194 -0
- package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/gjc-runtime/psmux-detect.d.ts +1 -1
- package/dist/types/gjc-runtime/python-transcript.d.ts +19 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +2 -8
- package/dist/types/gjc-runtime/session-layout.d.ts +6 -3
- package/dist/types/gjc-runtime/state-renderer.d.ts +0 -22
- package/dist/types/gjc-runtime/state-schema.d.ts +7 -7
- package/dist/types/gjc-runtime/tmux-common.d.ts +2 -2
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +38 -1
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +2 -24
- package/dist/types/gjc-runtime/ultragoal-validation-policy.d.ts +73 -0
- package/dist/types/gjc-runtime/workflow-recovery-projection.d.ts +100 -0
- package/dist/types/hooks/skill-keywords.d.ts +1 -1
- package/dist/types/main.d.ts +0 -10
- package/dist/types/modes/acp/acp-agent.d.ts +13 -6
- package/dist/types/modes/components/model-selector.d.ts +14 -0
- package/dist/types/modes/components/skill-hud/render.d.ts +6 -1
- package/dist/types/modes/components/smart-routing-panel.d.ts +82 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +14 -0
- package/dist/types/modes/interactive-mode.d.ts +3 -0
- package/dist/types/modes/types.d.ts +9 -0
- package/dist/types/rlm/artifacts.d.ts +4 -4
- package/dist/types/runtime/optional-runtime-services.d.ts +2 -1
- package/dist/types/runtime/workspace-tree-service.d.ts +5 -1
- package/dist/types/runtime-mcp/config.d.ts +6 -0
- package/dist/types/runtime-mcp/manager.d.ts +10 -0
- package/dist/types/sdk/acp/adapter.d.ts +0 -4
- package/dist/types/sdk/broker/broker.d.ts +1 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +57 -2
- package/dist/types/sdk/broker/session-index.d.ts +15 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +6 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -0
- package/dist/types/sdk/bus/index.d.ts +8 -0
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -2
- package/dist/types/sdk/client/client.d.ts +39 -4
- package/dist/types/sdk/host/host.d.ts +1 -0
- package/dist/types/sdk/host/internal-autorouting-state.d.ts +3 -0
- package/dist/types/sdk/host/model-pin.d.ts +29 -0
- package/dist/types/sdk/host/session-runtime.d.ts +2 -1
- package/dist/types/sdk/lifecycle-session.d.ts +13 -0
- package/dist/types/sdk/router/session-router.d.ts +27 -1
- package/dist/types/sdk/session.d.ts +11 -1
- package/dist/types/session/agent-session.d.ts +36 -6
- package/dist/types/session/artifacts.d.ts +16 -1
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
- package/dist/types/session/session-manager.d.ts +84 -2
- package/dist/types/session/session-staging-paths.d.ts +3 -0
- package/dist/types/skill-state/canonical-skills.d.ts +1 -1
- package/dist/types/skill-state/workflow-hud.d.ts +12 -21
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +1 -0
- package/dist/types/slash-commands/helpers/autorouting-status.d.ts +8 -0
- package/dist/types/system-prompt.d.ts +23 -0
- package/dist/types/task/executor.d.ts +35 -4
- package/dist/types/task/index.d.ts +17 -3
- package/dist/types/task/receipt.d.ts +3 -1
- package/dist/types/task/types.d.ts +144 -0
- package/dist/types/tools/atomic-file-write.d.ts +72 -0
- package/dist/types/tools/descriptors.d.ts +1 -0
- package/dist/types/tools/index.d.ts +36 -1
- package/dist/types/tools/move-session.d.ts +40 -0
- package/dist/types/tools/python.d.ts +12 -0
- package/dist/types/tools/resource-gc.d.ts +0 -3
- package/dist/types/tools/search.d.ts +8 -1
- package/dist/types/tools/skill.d.ts +9 -4
- package/dist/types/tools/subagent.d.ts +33 -3
- package/dist/types/utils/xml-escape.d.ts +2 -0
- package/dist/types/workflow/workflow-intent-diff.d.ts +2 -2
- package/dist/types/workflow/workflow-intent-report-consumer.d.ts +1 -1
- package/package.json +11 -12
- package/scripts/build-sdk-package-smoke.ts +7 -5
- package/scripts/check-autorouting-tier-map.ts +183 -0
- package/scripts/generate-sdk-operation-inventory.ts +12 -0
- package/scripts/generate-tool-catalog.ts +40 -5
- package/src/async/job-manager.ts +5 -2
- package/src/autoresearch/dashboard.ts +134 -314
- package/src/autoresearch/data-context.ts +35 -0
- package/src/autoresearch/git.ts +186 -26
- package/src/autoresearch/{helpers.ts → harness.ts} +65 -40
- package/src/autoresearch/{prompt-setup.md → prompts/prompt-setup.md} +7 -7
- package/src/autoresearch/prompts/prompt.md +103 -0
- package/src/autoresearch/prompts.ts +126 -0
- package/src/autoresearch/runs.ts +708 -0
- package/src/autoresearch/types.ts +9 -150
- package/src/capability/index.ts +4 -4
- package/src/capability/types.ts +20 -0
- package/src/cli/accounts-cli.ts +21 -5
- package/src/cli/config-cli.ts +25 -1
- package/src/cli/fast-help.ts +1 -2
- package/src/cli/list-models.ts +5 -8
- package/src/cli/setup-cli.ts +8 -0
- package/src/cli.ts +2 -21
- package/src/commands/autoresearch.ts +33 -0
- package/src/commands/coordinator.ts +15 -0
- package/src/commands/launch.ts +2 -4
- package/src/commands/quick-lane.ts +1 -1
- package/src/commands/sdk.ts +24 -0
- package/src/commands/state.ts +1 -1
- package/src/config/autorouting-contract.ts +474 -0
- package/src/config/autorouting-generator.ts +238 -0
- package/src/config/autorouting-tier-map.ts +6108 -0
- package/src/config/autorouting.ts +120 -0
- package/src/config/model-discovery-manager.ts +42 -11
- package/src/config/model-registry.ts +348 -68
- package/src/config/provider-selection-policy.ts +60 -9
- package/src/config/settings-schema.ts +195 -6
- package/src/config/settings.ts +62 -1
- package/src/config.ts +2 -3
- package/src/coordinator/contract.ts +0 -1
- package/src/coordinator-mcp/codex-handoff.ts +68 -42
- package/src/coordinator-mcp/durability.ts +200 -0
- package/src/coordinator-mcp/event-webhook.ts +278 -0
- package/src/coordinator-mcp/question-state.ts +109 -46
- package/src/coordinator-mcp/server.ts +932 -504
- package/src/crash/index-store.ts +126 -22
- package/src/crash/record-loader.ts +7 -0
- package/src/crash/upstream/relay.ts +82 -34
- package/src/cursor.ts +84 -1
- package/src/debug/index.ts +26 -0
- package/src/defaults/gjc/skills/autoresearch/SKILL.md +116 -0
- package/src/defaults/gjc/skills/autoresearch/auto-critic.md +46 -0
- package/src/defaults/gjc/skills/autoresearch/auto-iterate.md +42 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +17 -37
- package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -18
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +6 -17
- package/src/defaults/gjc/skills/ultragoal/ai-slop-cleaner.md +2 -2
- package/src/defaults/gjc-defaults.ts +89 -2
- package/src/defaults/gjc-skills.generated.ts +24 -17
- package/src/discovery/builtin.ts +18 -5
- package/src/discovery/helpers.ts +6 -6
- package/src/edit/index.ts +5 -2
- package/src/eval/py/executor.ts +8 -0
- package/src/extensibility/extensions/loader.ts +135 -13
- package/src/extensibility/extensions/wrapper.ts +1 -2
- package/src/extensibility/gjc-plugins/schema.ts +1 -1
- package/src/extensibility/runtime-skill-discovery.ts +2 -2
- package/src/extensibility/skill-management.ts +2 -3
- package/src/extensibility/skills.ts +16 -8
- package/src/gjc-runtime/autoresearch-runtime.ts +1509 -0
- package/src/gjc-runtime/gc-render.ts +0 -1
- package/src/gjc-runtime/gc-runtime.ts +1 -11
- package/src/gjc-runtime/launch-tmux.ts +3 -3
- package/src/gjc-runtime/psmux-detect.ts +2 -2
- package/src/gjc-runtime/python-transcript.ts +58 -0
- package/src/gjc-runtime/ralplan-runtime.ts +6 -18
- package/src/gjc-runtime/session-layout.ts +18 -7
- package/src/gjc-runtime/session-state-sidecar.ts +58 -9
- package/src/gjc-runtime/state-renderer.ts +0 -38
- package/src/gjc-runtime/state-runtime.ts +43 -22
- package/src/gjc-runtime/state-schema.ts +1 -1
- package/src/gjc-runtime/tmux-common.ts +7 -7
- package/src/gjc-runtime/ultragoal-change-set.ts +232 -11
- package/src/gjc-runtime/ultragoal-runtime.ts +309 -114
- package/src/gjc-runtime/ultragoal-validation-policy.ts +247 -0
- package/src/gjc-runtime/workflow-command-ref.ts +15 -11
- package/src/gjc-runtime/workflow-manifest.generated.json +413 -532
- package/src/gjc-runtime/workflow-manifest.ts +43 -83
- package/src/gjc-runtime/workflow-recovery-projection.ts +616 -0
- package/src/hooks/skill-keywords.ts +3 -3
- package/src/hooks/skill-state.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +26 -24
- package/src/lsp/index.ts +25 -5
- package/src/main.ts +2 -27
- package/src/modes/acp/acp-agent.ts +200 -75
- package/src/modes/components/model-selector.ts +216 -13
- package/src/modes/components/oauth-selector.ts +5 -5
- package/src/modes/components/skill-hud/render.ts +173 -35
- package/src/modes/components/smart-routing-panel.ts +531 -0
- package/src/modes/components/tool-status-header.ts +6 -3
- package/src/modes/controllers/command-controller.ts +17 -7
- package/src/modes/controllers/input-controller.ts +44 -9
- package/src/modes/controllers/runtime-mcp-command-controller.ts +4 -0
- package/src/modes/controllers/selector-controller.ts +298 -65
- package/src/modes/interactive-mode.ts +8 -1
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +1 -1
- package/src/modes/types.ts +9 -1
- package/src/prompts/agents/planner.md +1 -1
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/system/volatile-project-context.md +2 -1
- package/src/prompts/tools/move-session.md +15 -0
- package/src/prompts/tools/python.md +12 -0
- package/src/prompts/tools/skill-discovery.md +1 -1
- package/src/prompts/tools/skill.md +2 -2
- package/src/prompts/tools/task-summary.md +1 -0
- package/src/prompts/tools/task.md +6 -0
- package/src/rlm/artifacts.ts +12 -10
- package/src/runtime/optional-runtime-services.ts +3 -2
- package/src/runtime/workspace-tree-service.ts +11 -3
- package/src/runtime-mcp/config.ts +8 -1
- package/src/runtime-mcp/manager.ts +33 -0
- package/src/sdk/acp/adapter.ts +48 -1
- package/src/sdk/broker/broker.ts +30 -2
- package/src/sdk/broker/discovery.ts +217 -2
- package/src/sdk/broker/lifecycle.ts +385 -59
- package/src/sdk/broker/session-index.ts +243 -48
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/bus/chat-daemon-control.ts +8 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +5 -0
- package/src/sdk/bus/index.ts +208 -11
- package/src/sdk/bus/kind-aware-reconciliation.ts +16 -0
- package/src/sdk/bus/reconciliation-store.ts +27 -5
- package/src/sdk/bus/telegram-daemon-contract.ts +12 -2
- package/src/sdk/client/client.ts +204 -22
- package/src/sdk/host/host.ts +16 -0
- package/src/sdk/host/internal-autorouting-state.ts +13 -0
- package/src/sdk/host/model-pin.ts +101 -0
- package/src/sdk/host/reverse-leases.ts +2 -1
- package/src/sdk/host/session-runtime.test.ts +224 -1
- package/src/sdk/host/session-runtime.ts +125 -37
- package/src/sdk/lifecycle/service.ts +3 -1
- package/src/sdk/lifecycle-session.ts +42 -1
- package/src/sdk/protocol/operation-inventory.generated.json +66 -0
- package/src/sdk/router/session-router.ts +375 -36
- package/src/sdk/session.ts +547 -47
- package/src/session/account-inventory.ts +1 -1
- package/src/session/agent-session.ts +765 -189
- package/src/session/artifacts.ts +234 -4
- package/src/session/internal/managed-session-storage.ts +91 -4
- package/src/session/provider-safety-stop-hint.ts +3 -2
- package/src/session/session-manager.ts +775 -16
- package/src/session/session-staging-paths.ts +8 -0
- package/src/setup/hermes/templates/operator-instructions.v1.md +0 -1
- package/src/setup/host-plugin-setup.ts +2 -2
- package/src/skill-state/active-state.ts +2 -2
- package/src/skill-state/canonical-skills.ts +1 -1
- package/src/skill-state/initial-phase.ts +1 -1
- package/src/skill-state/workflow-hud.ts +41 -41
- package/src/skill-state/workflow-mutation-guard.ts +26 -7
- package/src/slash-commands/builtin-registry.ts +77 -0
- package/src/slash-commands/helpers/autorouting-status.ts +55 -0
- package/src/system-prompt.ts +102 -5
- package/src/task/discovery.ts +2 -3
- package/src/task/executor.ts +617 -43
- package/src/task/index.ts +262 -15
- package/src/task/receipt.ts +30 -0
- package/src/task/render.ts +11 -1
- package/src/task/types.ts +316 -0
- package/src/tools/atomic-file-write.ts +594 -0
- package/src/tools/bisect.ts +3 -2
- package/src/tools/descriptors.test.ts +3 -0
- package/src/tools/descriptors.ts +24 -0
- package/src/tools/image-gen.ts +5 -1
- package/src/tools/index.ts +62 -5
- package/src/tools/move-session.ts +107 -0
- package/src/tools/python.ts +205 -0
- package/src/tools/read.ts +88 -15
- package/src/tools/renderers.ts +2 -0
- package/src/tools/resource-gc.ts +8 -177
- package/src/tools/search.ts +30 -6
- package/src/tools/skill-discovery.ts +1 -0
- package/src/tools/skill.ts +37 -7
- package/src/tools/subagent-render.ts +119 -13
- package/src/tools/subagent.ts +91 -74
- package/src/tools/tool-catalog.generated.ts +64 -2
- package/src/tools/write.ts +16 -12
- package/src/utils/xml-escape.ts +14 -0
- package/src/web/search/providers/codex.ts +2 -2
- package/src/workflow/workflow-intent-diff.ts +13 -12
- package/src/workflow/workflow-intent-report-consumer.ts +6 -6
- package/dist/types/autoresearch/helpers.d.ts +0 -24
- package/dist/types/autoresearch/index.d.ts +0 -2
- package/dist/types/autoresearch/state.d.ts +0 -17
- package/dist/types/autoresearch/storage.d.ts +0 -142
- package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
- package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
- package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
- package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
- package/dist/types/commands/team.d.ts +0 -24
- package/dist/types/gjc-runtime/team-gc.d.ts +0 -7
- package/dist/types/gjc-runtime/team-launch.d.ts +0 -61
- package/dist/types/gjc-runtime/team-notify.d.ts +0 -45
- package/dist/types/gjc-runtime/team-runtime.d.ts +0 -336
- package/dist/types/gjc-runtime/team-store.d.ts +0 -168
- package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +0 -43
- package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +0 -92
- package/dist/types/gjc-runtime/team-workers.d.ts +0 -83
- package/dist/types/rlm/index.d.ts +0 -47
- package/dist/types/rlm/preset.d.ts +0 -23
- package/dist/types/rlm/python-tool.d.ts +0 -16
- package/src/autoresearch/command-resume.md +0 -14
- package/src/autoresearch/index.ts +0 -536
- package/src/autoresearch/prompt.md +0 -103
- package/src/autoresearch/resume-message.md +0 -10
- package/src/autoresearch/state.ts +0 -273
- package/src/autoresearch/storage.ts +0 -699
- package/src/autoresearch/tools/init-experiment.ts +0 -272
- package/src/autoresearch/tools/log-experiment.ts +0 -524
- package/src/autoresearch/tools/run-experiment.ts +0 -475
- package/src/autoresearch/tools/update-notes.ts +0 -109
- package/src/commands/rlm.ts +0 -19
- package/src/commands/team.ts +0 -238
- package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +0 -42
- package/src/defaults/gjc/skills/team/SKILL.md +0 -467
- package/src/gjc-runtime/team-gc.ts +0 -49
- package/src/gjc-runtime/team-launch.ts +0 -404
- package/src/gjc-runtime/team-notify.ts +0 -326
- package/src/gjc-runtime/team-runtime.ts +0 -5923
- package/src/gjc-runtime/team-store.ts +0 -878
- package/src/gjc-runtime/team-worker-heartbeat.ts +0 -149
- package/src/gjc-runtime/team-worker-memory-guard.ts +0 -363
- package/src/gjc-runtime/team-workers.ts +0 -1123
- package/src/prompts/system/rlm-report-command.md +0 -1
- package/src/prompts/system/rlm-research.md +0 -23
- package/src/rlm/index.ts +0 -365
- package/src/rlm/preset.ts +0 -76
- package/src/rlm/python-tool.ts +0 -68
|
@@ -50,6 +50,7 @@ gjc ultragoal create-goals --brief "<brief>"
|
|
|
50
50
|
gjc ultragoal create-goals --brief-file <path>
|
|
51
51
|
gjc ultragoal complete-goals
|
|
52
52
|
gjc ultragoal complete-goals --retry-failed
|
|
53
|
+
gjc ultragoal quality-gate source-hash --json
|
|
53
54
|
gjc ultragoal quality-gate validate --quality-gate-json <quality-gate-json-or-path> [--goal-id <id>] [--json]
|
|
54
55
|
gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<evidence>" --quality-gate-json <quality-gate-json-or-path>
|
|
55
56
|
gjc ultragoal checkpoint --goal-id <id> --status failed --evidence "<blocker/evidence>"
|
|
@@ -230,17 +231,17 @@ The Ultragoal leader owns `.gjc/_session-{sessionid}/ultragoal/goals.json` and `
|
|
|
230
231
|
|
|
231
232
|
### Native executor parallelism contract
|
|
232
233
|
|
|
233
|
-
Native subagent parallelism is a contract for bounded `executor` delegation, not a runtime scheduler
|
|
234
|
+
Native subagent parallelism is a contract for bounded `executor` delegation, not a runtime scheduler:
|
|
234
235
|
|
|
235
236
|
- **Use native `executor` parallelism only** when a story's expected diffs fall in genuinely different sub-domains/modules/systems, each boundable by a per-slice coordination contract.
|
|
236
237
|
- **Default to direct leader edits** otherwise; sequence any work with real dependencies, shared-file overlap, or a single-domain footprint, and never parallelize work that lacks a safe contract.
|
|
237
238
|
- Worker agents **MUST NOT mutate `.gjc/_session-{sessionid}/ultragoal`**, call goal tools, make checkpoint decisions, own integration, or own final verification. The Ultragoal leader keeps those responsibilities.
|
|
239
|
+
- Workers must not run `gjc ultragoal checkpoint`: checkpoint authority stays with the leader after worker tasks are terminal. The leader checkpoints from worker evidence plus the current-session GJC goal snapshot, and performs no hidden goal mutation.
|
|
238
240
|
|
|
239
241
|
Before workers start, each per-slice coordination contract MUST name the target files/surfaces, independence assumptions, allowed coordination channel, conflict-escalation rule, expected evidence, and terminal status. Conflict or assignment changes remain leader-owned and must be auditable through durable ledger evidence.
|
|
240
242
|
|
|
241
243
|
For failed, timed-out, or contract-violating slices, record durable ledger evidence; preserve successful terminal slices only when safe; and reassign, retry, or collapse the invalid work to serial execution under an updated contract. Completion after parallel work still requires terminal worker evidence, leader integration, targeted verification, and the existing cleaner + architect + executor QA/red-team gate before checkpoint complete.
|
|
242
244
|
|
|
243
|
-
Team remains explicit and separate: Team is not auto-launched, not a hidden pipeline scheduler, and never owns Ultragoal goals, checkpoints, or ledger state.
|
|
244
245
|
|
|
245
246
|
## Boundary verification (aggregate default)
|
|
246
247
|
|
|
@@ -282,18 +283,6 @@ Checkpoint contract summary — the full contract lives in the `validation-batch
|
|
|
282
283
|
|
|
283
284
|
Cohort lanes are parallel by construction: the boundary gate freezes one `sourceHash` first, so `cleaner`, `architect`, and `qa` can run concurrently against the identical immutable snapshot and then join. Fall back to **sequential** lanes only when code is still changing (nothing can be frozen yet), when the red-team lane depends on architect fixes, or when architect findings gate the QA scope. Either way the lanes must **join before checkpoint** — no lane checkpoints independently, and repair work starts only after the join.
|
|
284
285
|
|
|
285
|
-
## Use Ultragoal and Team together
|
|
286
|
-
|
|
287
|
-
Use ultragoal and team together for a durable Ultragoal story that benefits from one visible tmux worker session. Ultragoal remains leader-owned: `.gjc/_session-{sessionid}/ultragoal/goals.json` stores the story plan and `.gjc/_session-{sessionid}/ultragoal/ledger.jsonl` stores checkpoints. Team is the single-worker tmux execution engine and returns task/evidence status to the leader.
|
|
288
|
-
|
|
289
|
-
The leader checkpoints Ultragoal from Team evidence plus the current-session GJC goal snapshot; durable state remains leader-owned in `goals.json` and `ledger.jsonl`:
|
|
290
|
-
|
|
291
|
-
```sh
|
|
292
|
-
gjc ultragoal checkpoint --goal-id <id> --status complete --evidence "<team evidence mentioning .gjc/_session-{sessionid}/ultragoal and <id>>" --quality-gate-json <quality-gate-json-or-path>
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
Workers do not own ultragoal goal state, do not create worker ultragoal ledgers, and do not checkpoint Ultragoal. Workers must not run `gjc ultragoal checkpoint`; checkpoint authority stays with the leader after worker tasks are terminal. Team launch remains explicit; Ultragoal does not auto-launch Team and performs no hidden goal mutation.
|
|
296
|
-
|
|
297
286
|
## Internal Ultragoal sub-skill fragments
|
|
298
287
|
|
|
299
288
|
The completion-gate cleanup sweep is driven by `ai-slop-cleaner`, an internal Ultragoal sub-skill bundled as a `kind: "skill-fragment"` prompt with parent skill `ultragoal` (installed at `skill-fragments/ultragoal/ai-slop-cleaner.md`). It is analogous to deep-interview's auto-research fragment: loaded on demand for one specific hook, never a user-facing skill.
|
|
@@ -302,7 +291,7 @@ The completion-gate cleanup sweep is driven by `ai-slop-cleaner`, an internal Ul
|
|
|
302
291
|
- It is a read-only detector+reporter over the active story's changed files only: it never edits code, writes files, mutates `.gjc/`, checkpoints, calls goal tools, or spawns workflows.
|
|
303
292
|
- It classifies every finding as blocking or advisory across the full taxonomy (fallback-like masking vs. grounded, duplication, dead code, needless abstraction, boundary violations, UI/design slop, missing tests).
|
|
304
293
|
- The leader and a leader-spawned `executor` own all fixes; the cleaner reruns until zero blocking findings remain. Advisory findings live in the gate report only.
|
|
305
|
-
- Recursion guard: it must not spawn nested `ralplan`/`
|
|
294
|
+
- Recursion guard: it must not spawn nested `ralplan`/`deep-interview`/`ultragoal`; broad or architectural findings are handed back to the leader as review blockers.
|
|
306
295
|
|
|
307
296
|
## Boundary completion cohort gate
|
|
308
297
|
|
|
@@ -311,7 +300,7 @@ The heavyweight gate runs **once per boundary generation**, not once per story a
|
|
|
311
300
|
One generation freezes the change set and reviews it exactly once:
|
|
312
301
|
|
|
313
302
|
1. Run implementation verification for the boundary's cumulative change set.
|
|
314
|
-
2. **Freeze the change set.**
|
|
303
|
+
2. **Freeze the change set.** Run `gjc ultragoal quality-gate source-hash --json` on the clean reviewed snapshot and use its `sourceHash` exactly. The runtime binds this digest to the integration base, merge base, normalized changed paths, captured diff, and untracked-content digest. Every lane in this generation inspects that same frozen snapshot; a lane verdict carrying a different `sourceHash` is rejected. Any later source or base change requires rerunning this command and starting a new generation.
|
|
315
304
|
3. **Run the cohort lanes on the frozen snapshot** — at most one `cleaner`, one `architect`, and one `qa` lane per generation. They may run in parallel because they share the frozen source; a second architect or QA lane in the same generation is rejected. The `cleaner` lane is the internal ai-slop-cleaner skill fragment run over the frozen change set: a read-only detector that emits an `AI SLOP CLEANUP REPORT`, and it still runs and records a passed/no-op report when there are no relevant edits. Its BLOCKING findings join the cohort findings rather than starting their own fix loop; advisory findings are included in the gate report only and are not written to the Ultragoal ledger.
|
|
316
305
|
4. Delegate an `architect` review covering all three lanes:
|
|
317
306
|
- architecture-side: system boundaries, layering, data/control flow, operational risks.
|
|
@@ -429,7 +418,7 @@ The critic must verify that the `human_blocked` classification is genuine, inclu
|
|
|
429
418
|
|
|
430
419
|
### Invocation and containment
|
|
431
420
|
|
|
432
|
-
At each terminus, the leader gives the read-only `critic` role agent `brief.md`, `goals.json`, `ledger.jsonl`, and the cumulative change set. For completion, invoke it before assembling the final-aggregate gate JSON. For pause, invoke it after the `human_blocked` classification and before `goal({"op":"pause"})`. The terminal critic must not spawn nested `ralplan`, `
|
|
421
|
+
At each terminus, the leader gives the read-only `critic` role agent `brief.md`, `goals.json`, `ledger.jsonl`, and the cumulative change set. For completion, invoke it before assembling the final-aggregate gate JSON. For pause, invoke it after the `human_blocked` classification and before `goal({"op":"pause"})`. The terminal critic must not spawn nested `ralplan`, `deep-interview`, or `ultragoal` workflows. This creates no interactive surface: `ask` remains blocked while an Ultragoal run is active.
|
|
433
422
|
|
|
434
423
|
On repeat terminus attempts within the same run (after an `ITERATE`/`REJECT` reopen cycle or a superseded pause classification), **resume the prior terminal-critic subagent when resumable** instead of freshly spawning one: the critic already holds `brief.md`, `goals.json`, the ledger history, and its own prior findings, so re-invocation only needs the delta (new ledger events, the updated cumulative change set, and evidence addressing the prior blockers). Resume via existing `subagent` resume/steer controls; on `context_unavailable`, `not_found`, `no_runner`, or `resume_failed` — or after a process restart — fall back to a fresh `critic` spawn with the full context bundle. A resumed terminal critic remains read-only, keeps the same containment rules, and must issue a fresh verdict against the current state — a prior `ITERATE` is never carried forward as pre-judged, and each verdict is still recorded through `gjc ultragoal record-critic-verdict`.
|
|
435
424
|
|
|
@@ -9,7 +9,7 @@ You are a **read-only detector and reporter**. You never edit code, write files,
|
|
|
9
9
|
- Inspect ONLY the active Ultragoal story's changed-files list. No broad rewrites, no inspection outside that scope, no new dependencies.
|
|
10
10
|
- Allow only narrow supporting reads needed to understand the contracts of changed files; if you need broader context, report that need to the leader instead of expanding scope.
|
|
11
11
|
- If there are no relevant edits, emit a passed/no-op report (`Gate Result: PASS`, `Changed Files Reviewed` listing the files as "no relevant edits").
|
|
12
|
-
- Recursion guard: you are already inside an Ultragoal workflow. Do NOT spawn nested `ralplan`, `
|
|
12
|
+
- Recursion guard: you are already inside an Ultragoal workflow. Do NOT spawn nested `ralplan`, `autoresearch`, `deep-interview`, or `ultragoal` workflows. Broad, ambiguous, cross-layer, or architectural findings are handed to the leader as review blockers, not resolved here.
|
|
13
13
|
|
|
14
14
|
## Taxonomy
|
|
15
15
|
|
|
@@ -46,7 +46,7 @@ Advisory Findings: [none, or numbered findings with file, category, evidence, wh
|
|
|
46
46
|
Fallback Findings: [none, or finding -> masking fallback slop / grounded compatibility/fail-safe fallback -> blocking/advisory]
|
|
47
47
|
UI/Design Findings: [none/N/A, or signal -> blocking/advisory -> rationale]
|
|
48
48
|
Missing Test Findings: [none, or gap -> blocking/advisory -> required coverage]
|
|
49
|
-
Recursion Guard: [confirmed no nested ralplan/
|
|
49
|
+
Recursion Guard: [confirmed no nested ralplan/autoresearch/deep-interview/ultragoal spawned; broad findings handed to leader]
|
|
50
50
|
Changed Files Reviewed:
|
|
51
51
|
- [path] - [reviewed / no relevant edits]
|
|
52
52
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import { getAgentDir, isEnoent } from "@gajae-code/utils";
|
|
4
5
|
import { BUNDLED_GJC_SKILL_CATALOG, type BundledGjcSkillCatalogEntry } from "./gjc-skills.generated";
|
|
5
6
|
|
|
6
|
-
export const DEFAULT_GJC_DEFINITION_NAMES = ["deep-interview", "ralplan", "
|
|
7
|
+
export const DEFAULT_GJC_DEFINITION_NAMES = ["autoresearch", "deep-interview", "ralplan", "ultragoal"] as const;
|
|
7
8
|
export type DefaultGjcDefinitionName = (typeof DEFAULT_GJC_DEFINITION_NAMES)[number];
|
|
8
9
|
export type DefaultGjcDefinitionKind = "skill" | "skill-fragment";
|
|
9
10
|
export type EmbeddedDefaultGjcSkill = {
|
|
@@ -64,6 +65,32 @@ export type DefaultGjcDefinitionInstallFile =
|
|
|
64
65
|
status: DefaultGjcInstallStatus;
|
|
65
66
|
};
|
|
66
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Bundled workflow definitions that GJC used to ship and no longer does.
|
|
70
|
+
*
|
|
71
|
+
* Installing defaults only ever wrote the CURRENT set, so a definition dropped
|
|
72
|
+
* from the bundle stayed on disk under the agent dir forever — where
|
|
73
|
+
* filesystem skill discovery still found it and `/skill:<name>` still resolved.
|
|
74
|
+
* `team` was the first removal, so it was the first to expose that gap.
|
|
75
|
+
*
|
|
76
|
+
* Retirement QUARANTINES rather than deletes: the directory is moved aside to
|
|
77
|
+
* `<targetRoot>/retired/<name>.<timestamp>/`. A user who customized the skill
|
|
78
|
+
* keeps their content, and nothing is destroyed to satisfy a rename.
|
|
79
|
+
*/
|
|
80
|
+
export const RETIRED_GJC_DEFINITION_NAMES = ["team"] as const;
|
|
81
|
+
export type RetiredGjcDefinitionName = (typeof RETIRED_GJC_DEFINITION_NAMES)[number];
|
|
82
|
+
|
|
83
|
+
export type RetiredGjcDefinitionStatus = "absent" | "quarantined";
|
|
84
|
+
|
|
85
|
+
export interface RetiredGjcDefinitionFile {
|
|
86
|
+
name: RetiredGjcDefinitionName;
|
|
87
|
+
/** Directory that held the retired definition. */
|
|
88
|
+
path: string;
|
|
89
|
+
/** Where it was moved, when quarantined. */
|
|
90
|
+
quarantinedTo?: string;
|
|
91
|
+
status: RetiredGjcDefinitionStatus;
|
|
92
|
+
}
|
|
93
|
+
|
|
67
94
|
export interface DefaultGjcDefinitionInstallResult {
|
|
68
95
|
targetRoot: string;
|
|
69
96
|
total: number;
|
|
@@ -73,6 +100,8 @@ export interface DefaultGjcDefinitionInstallResult {
|
|
|
73
100
|
missing: number;
|
|
74
101
|
different: number;
|
|
75
102
|
files: DefaultGjcDefinitionInstallFile[];
|
|
103
|
+
/** Retired bundled definitions found under `targetRoot`, and what happened to them. */
|
|
104
|
+
retired: RetiredGjcDefinitionFile[];
|
|
76
105
|
}
|
|
77
106
|
function sourcePathForBundledEntry(entry: BundledGjcSkillCatalogEntry): string {
|
|
78
107
|
const relative = entry.kind === "skill" ? entry.relativePath : entry.relativePath.replace(/^skill-fragments\//, "");
|
|
@@ -236,7 +265,63 @@ export async function installDefaultGjcDefinitions(
|
|
|
236
265
|
}
|
|
237
266
|
}
|
|
238
267
|
|
|
239
|
-
|
|
268
|
+
const retired = await retireRemovedGjcDefinitions(targetRoot, { check: options.check === true });
|
|
269
|
+
return summarizeInstallResult(targetRoot, files, retired);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Quarantine any retired bundled definition still present under `targetRoot`.
|
|
274
|
+
*
|
|
275
|
+
* `check` reports what WOULD move without touching the filesystem, so
|
|
276
|
+
* `--check` callers stay read-only.
|
|
277
|
+
*/
|
|
278
|
+
export async function retireRemovedGjcDefinitions(
|
|
279
|
+
targetRoot: string,
|
|
280
|
+
options: { check?: boolean } = {},
|
|
281
|
+
): Promise<RetiredGjcDefinitionFile[]> {
|
|
282
|
+
const results: RetiredGjcDefinitionFile[] = [];
|
|
283
|
+
for (const name of RETIRED_GJC_DEFINITION_NAMES) {
|
|
284
|
+
const directory = path.join(targetRoot, "skills", name);
|
|
285
|
+
if (!(await directoryExists(directory))) {
|
|
286
|
+
results.push({ name, path: directory, status: "absent" });
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (options.check) {
|
|
290
|
+
results.push({ name, path: directory, status: "quarantined" });
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
const quarantinedTo = await reserveQuarantinePath(path.join(targetRoot, "retired"), name);
|
|
294
|
+
await fs.rename(directory, quarantinedTo);
|
|
295
|
+
results.push({ name, path: directory, quarantinedTo, status: "quarantined" });
|
|
296
|
+
}
|
|
297
|
+
return results;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Reserve a unique quarantine directory.
|
|
302
|
+
*
|
|
303
|
+
* A timestamp alone is not enough: two retirements inside the same millisecond
|
|
304
|
+
* resolve to the same path, which would silently overwrite the earlier
|
|
305
|
+
* quarantine. Disambiguate with a counter until an unused path is found.
|
|
306
|
+
*/
|
|
307
|
+
async function reserveQuarantinePath(retiredRoot: string, name: string): Promise<string> {
|
|
308
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
309
|
+
await fs.mkdir(retiredRoot, { recursive: true });
|
|
310
|
+
const base = path.join(retiredRoot, `${name}.${stamp}`);
|
|
311
|
+
if (!(await directoryExists(base))) return base;
|
|
312
|
+
for (let attempt = 2; ; attempt += 1) {
|
|
313
|
+
const candidate = `${base}-${attempt}`;
|
|
314
|
+
if (!(await directoryExists(candidate))) return candidate;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async function directoryExists(candidate: string): Promise<boolean> {
|
|
319
|
+
try {
|
|
320
|
+
return (await fs.stat(candidate)).isDirectory();
|
|
321
|
+
} catch (error) {
|
|
322
|
+
if (isEnoent(error)) return false;
|
|
323
|
+
throw error;
|
|
324
|
+
}
|
|
240
325
|
}
|
|
241
326
|
|
|
242
327
|
async function readExistingText(filePath: string): Promise<string | undefined> {
|
|
@@ -251,6 +336,7 @@ async function readExistingText(filePath: string): Promise<string | undefined> {
|
|
|
251
336
|
function summarizeInstallResult(
|
|
252
337
|
targetRoot: string,
|
|
253
338
|
files: DefaultGjcDefinitionInstallFile[],
|
|
339
|
+
retired: RetiredGjcDefinitionFile[],
|
|
254
340
|
): DefaultGjcDefinitionInstallResult {
|
|
255
341
|
return {
|
|
256
342
|
targetRoot,
|
|
@@ -261,6 +347,7 @@ function summarizeInstallResult(
|
|
|
261
347
|
missing: countStatus(files, "missing"),
|
|
262
348
|
different: countStatus(files, "different"),
|
|
263
349
|
files,
|
|
350
|
+
retired,
|
|
264
351
|
};
|
|
265
352
|
}
|
|
266
353
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Keep this module metadata-only: skill bodies are loaded through literal
|
|
5
5
|
* dynamic imports only when a caller asks for their content.
|
|
6
6
|
*/
|
|
7
|
-
export type BundledGjcSkillName = "
|
|
7
|
+
export type BundledGjcSkillName = "autoresearch" | "deep-interview" | "ralplan" | "ultragoal";
|
|
8
8
|
|
|
9
9
|
export interface BundledGjcSkillCatalogEntry {
|
|
10
10
|
readonly kind: "skill" | "skill-fragment";
|
|
@@ -19,17 +19,14 @@ const deepInterview = () =>
|
|
|
19
19
|
import("./gjc/skills/deep-interview/SKILL.md", { with: { type: "text" } }).then(module => module.default);
|
|
20
20
|
const ralplan = () =>
|
|
21
21
|
import("./gjc/skills/ralplan/SKILL.md", { with: { type: "text" } }).then(module => module.default);
|
|
22
|
-
const
|
|
22
|
+
const autoresearch = () =>
|
|
23
|
+
import("./gjc/skills/autoresearch/SKILL.md", { with: { type: "text" } }).then(module => module.default);
|
|
23
24
|
const ultragoal = () =>
|
|
24
25
|
import("./gjc/skills/ultragoal/SKILL.md", { with: { type: "text" } }).then(module => module.default);
|
|
25
26
|
const autoAnswerUncertain = () =>
|
|
26
27
|
import("./gjc/skills/deep-interview/auto-answer-uncertain.md", { with: { type: "text" } }).then(
|
|
27
28
|
module => module.default,
|
|
28
29
|
);
|
|
29
|
-
const autoResearchGreenfield = () =>
|
|
30
|
-
import("./gjc/skills/deep-interview/auto-research-greenfield.md", { with: { type: "text" } }).then(
|
|
31
|
-
module => module.default,
|
|
32
|
-
);
|
|
33
30
|
const lateralReviewPanel = () =>
|
|
34
31
|
import("./gjc/skills/deep-interview/lateral-review-panel.md", { with: { type: "text" } }).then(
|
|
35
32
|
module => module.default,
|
|
@@ -40,6 +37,10 @@ const validationBatchContracts = () =>
|
|
|
40
37
|
import("./gjc/skills/ultragoal/validation-batch-contracts.md", { with: { type: "text" } }).then(
|
|
41
38
|
module => module.default,
|
|
42
39
|
);
|
|
40
|
+
const autoresearchIterate = () =>
|
|
41
|
+
import("./gjc/skills/autoresearch/auto-iterate.md", { with: { type: "text" } }).then(module => module.default);
|
|
42
|
+
const autoresearchCritic = () =>
|
|
43
|
+
import("./gjc/skills/autoresearch/auto-critic.md", { with: { type: "text" } }).then(module => module.default);
|
|
43
44
|
|
|
44
45
|
export const BUNDLED_GJC_SKILL_CATALOG: readonly BundledGjcSkillCatalogEntry[] = [
|
|
45
46
|
{
|
|
@@ -53,15 +54,15 @@ export const BUNDLED_GJC_SKILL_CATALOG: readonly BundledGjcSkillCatalogEntry[] =
|
|
|
53
54
|
kind: "skill",
|
|
54
55
|
name: "ralplan",
|
|
55
56
|
relativePath: "skills/ralplan/SKILL.md",
|
|
56
|
-
description: "Consensus planning entrypoint that auto-gates vague
|
|
57
|
+
description: "Consensus planning entrypoint that auto-gates vague ultragoal requests before execution",
|
|
57
58
|
loadContent: ralplan,
|
|
58
59
|
},
|
|
59
60
|
{
|
|
60
61
|
kind: "skill",
|
|
61
|
-
name: "
|
|
62
|
-
relativePath: "skills/
|
|
63
|
-
description: "
|
|
64
|
-
loadContent:
|
|
62
|
+
name: "autoresearch",
|
|
63
|
+
relativePath: "skills/autoresearch/SKILL.md",
|
|
64
|
+
description: "Goal-directed research missions interleaving web and data evidence into a structured verdict",
|
|
65
|
+
loadContent: autoresearch,
|
|
65
66
|
},
|
|
66
67
|
{
|
|
67
68
|
kind: "skill",
|
|
@@ -70,12 +71,6 @@ export const BUNDLED_GJC_SKILL_CATALOG: readonly BundledGjcSkillCatalogEntry[] =
|
|
|
70
71
|
description: "Create and execute durable repo-native multi-goal plans over GJC goal mode artifacts.",
|
|
71
72
|
loadContent: ultragoal,
|
|
72
73
|
},
|
|
73
|
-
{
|
|
74
|
-
kind: "skill-fragment",
|
|
75
|
-
parentSkillName: "deep-interview",
|
|
76
|
-
relativePath: "skill-fragments/deep-interview/auto-research-greenfield.md",
|
|
77
|
-
loadContent: autoResearchGreenfield,
|
|
78
|
-
},
|
|
79
74
|
{
|
|
80
75
|
kind: "skill-fragment",
|
|
81
76
|
parentSkillName: "deep-interview",
|
|
@@ -100,4 +95,16 @@ export const BUNDLED_GJC_SKILL_CATALOG: readonly BundledGjcSkillCatalogEntry[] =
|
|
|
100
95
|
relativePath: "skill-fragments/ultragoal/validation-batch-contracts.md",
|
|
101
96
|
loadContent: validationBatchContracts,
|
|
102
97
|
},
|
|
98
|
+
{
|
|
99
|
+
kind: "skill-fragment",
|
|
100
|
+
parentSkillName: "autoresearch",
|
|
101
|
+
relativePath: "skill-fragments/autoresearch/auto-iterate.md",
|
|
102
|
+
loadContent: autoresearchIterate,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
kind: "skill-fragment",
|
|
106
|
+
parentSkillName: "autoresearch",
|
|
107
|
+
relativePath: "skill-fragments/autoresearch/auto-critic.md",
|
|
108
|
+
loadContent: autoresearchCritic,
|
|
109
|
+
},
|
|
103
110
|
];
|
package/src/discovery/builtin.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Primary provider for GJC native configs. Supports all capabilities.
|
|
5
5
|
*/
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import { logger, parseFrontmatter, tryParseJson } from "@gajae-code/utils";
|
|
7
|
+
import { getAgentDir, logger, parseFrontmatter, tryParseJson } from "@gajae-code/utils";
|
|
8
8
|
import { YAML } from "bun";
|
|
9
9
|
import { registerProvider } from "../capability";
|
|
10
10
|
import { type ContextFile, contextFileCapability } from "../capability/context-file";
|
|
@@ -45,6 +45,20 @@ function getUserAgentDirs(): string[] {
|
|
|
45
45
|
return [PATHS.userAgent];
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* GJC's user-scope config directory.
|
|
50
|
+
*
|
|
51
|
+
* Home-relative `<home>/.gjc/agent` is only its default location: an agent
|
|
52
|
+
* directory profile (`--agent-dir`, `GJC_CODING_AGENT_DIR`, `setAgentDir()`)
|
|
53
|
+
* moves the whole user scope, and the writers (`getMCPConfigPath("user")` and
|
|
54
|
+
* everything `gjc mcp add` reaches) already follow it. Resolving from the home
|
|
55
|
+
* default instead would hide a profile's own registrations and load the default
|
|
56
|
+
* profile's servers into it.
|
|
57
|
+
*/
|
|
58
|
+
function resolveUserAgentDir(ctx: LoadContext): string {
|
|
59
|
+
return ctx.userAgentDir ?? getAgentDir();
|
|
60
|
+
}
|
|
61
|
+
|
|
48
62
|
function getProjectConfigDirs(): string[] {
|
|
49
63
|
return [PATHS.projectDir];
|
|
50
64
|
}
|
|
@@ -226,15 +240,14 @@ async function loadMCPServers(ctx: LoadContext): Promise<LoadResult<MCPServer>>
|
|
|
226
240
|
return result;
|
|
227
241
|
};
|
|
228
242
|
|
|
243
|
+
const userAgentDir = resolveUserAgentDir(ctx);
|
|
229
244
|
const paths = [
|
|
230
245
|
...getProjectConfigDirs().flatMap(projectConfigDir => [
|
|
231
246
|
{ path: path.join(ctx.cwd, projectConfigDir, "mcp.json"), level: "project" as const },
|
|
232
247
|
{ path: path.join(ctx.cwd, projectConfigDir, ".mcp.json"), level: "project" as const },
|
|
233
248
|
]),
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
{ path: path.join(ctx.home, userAgentDir, ".mcp.json"), level: "user" as const },
|
|
237
|
-
]),
|
|
249
|
+
{ path: path.join(userAgentDir, "mcp.json"), level: "user" as const },
|
|
250
|
+
{ path: path.join(userAgentDir, ".mcp.json"), level: "user" as const },
|
|
238
251
|
];
|
|
239
252
|
|
|
240
253
|
const contents = await Promise.allSettled(
|
package/src/discovery/helpers.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
|
-
import * as os from "node:os";
|
|
3
2
|
import * as path from "node:path";
|
|
4
3
|
import type { ThinkingLevel } from "@gajae-code/agent-core";
|
|
5
4
|
import type { FileType as FileTypeEnum, glob as globFn } from "@gajae-code/natives";
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
getConfigDirName,
|
|
9
8
|
getPluginsDir,
|
|
10
9
|
getProjectDir,
|
|
10
|
+
getTrustedHomeDir,
|
|
11
11
|
logger,
|
|
12
12
|
parseFrontmatter,
|
|
13
13
|
tryParseJson,
|
|
@@ -795,8 +795,8 @@ export function parseClaudePluginsRegistry(content: string): ClaudePluginsRegist
|
|
|
795
795
|
*/
|
|
796
796
|
export async function resolveActiveProjectRegistryPath(cwd: string): Promise<string | null> {
|
|
797
797
|
// Pass 1: walk up looking for an existing .gjc/ directory (nearest wins).
|
|
798
|
-
// Stop before
|
|
799
|
-
const homeDir =
|
|
798
|
+
// Stop before the provenance-checked home — ~/.gjc/ is the user-level config dir, not a project root.
|
|
799
|
+
const homeDir = getTrustedHomeDir();
|
|
800
800
|
let dir = path.resolve(cwd);
|
|
801
801
|
while (dir !== homeDir) {
|
|
802
802
|
try {
|
|
@@ -837,7 +837,7 @@ export async function resolveActiveProjectRegistryPath(cwd: string): Promise<str
|
|
|
837
837
|
* bootstrapped directory (no .gjc/ or .git/ yet) works: writeInstalledPluginsRegistry auto-creates
|
|
838
838
|
* the directory tree on first write.
|
|
839
839
|
*
|
|
840
|
-
* Returns undefined when cwd is
|
|
840
|
+
* Returns undefined when cwd is the trusted home — that path is already the user registry and must
|
|
841
841
|
* never alias as the project registry.
|
|
842
842
|
*/
|
|
843
843
|
export async function resolveOrDefaultProjectRegistryPath(cwd: string): Promise<string | undefined> {
|
|
@@ -846,7 +846,7 @@ export async function resolveOrDefaultProjectRegistryPath(cwd: string): Promise<
|
|
|
846
846
|
// Home directory must not be treated as a project root: the fallback path would alias
|
|
847
847
|
// getInstalledPluginsRegistryPath(), causing MarketplaceManager to load the same file
|
|
848
848
|
// as both user and project registry and producing duplicates / disambiguation errors.
|
|
849
|
-
if (path.resolve(cwd) ===
|
|
849
|
+
if (path.resolve(cwd) === getTrustedHomeDir()) return undefined;
|
|
850
850
|
return path.join(cwd, getConfigDirName(), "plugins", "installed_plugins.json");
|
|
851
851
|
}
|
|
852
852
|
|
|
@@ -873,7 +873,7 @@ export async function listClaudePluginRoots(
|
|
|
873
873
|
const projectRoots: ClaudePluginRoot[] = [];
|
|
874
874
|
|
|
875
875
|
// ── GJC installed plugins registry ───────────────────────────────────────
|
|
876
|
-
// In production `home` is
|
|
876
|
+
// In production `home` is the provenance-checked home, so `getPluginsDir(home)` resolves to the
|
|
877
877
|
// same XDG-aware path the marketplace writer uses (reads and writes always agree).
|
|
878
878
|
// Tests pass a temp dir, which short-circuits the resolver for deterministic isolation.
|
|
879
879
|
const gjcRegistryPath = path.join(getPluginsDir(home), "installed_plugins.json");
|
package/src/edit/index.ts
CHANGED
|
@@ -337,7 +337,10 @@ export class EditTool implements AgentTool<TInput> {
|
|
|
337
337
|
readonly #vimTool: VimTool;
|
|
338
338
|
readonly #pendingDeferredFetches = new Map<string, AbortController>();
|
|
339
339
|
|
|
340
|
-
constructor(
|
|
340
|
+
constructor(
|
|
341
|
+
private readonly session: ToolSession,
|
|
342
|
+
private readonly modeOverride?: EditMode,
|
|
343
|
+
) {
|
|
341
344
|
const { PI_EDIT_FUZZY: editFuzzy = "auto", PI_EDIT_FUZZY_THRESHOLD: editFuzzyThreshold = "auto" } = Bun.env;
|
|
342
345
|
|
|
343
346
|
// Fail fast on an invalid forced env variant; the shared resolver owns
|
|
@@ -350,7 +353,7 @@ export class EditTool implements AgentTool<TInput> {
|
|
|
350
353
|
}
|
|
351
354
|
|
|
352
355
|
get mode(): EditMode {
|
|
353
|
-
return resolveEditMode(this.session);
|
|
356
|
+
return this.modeOverride ?? resolveEditMode(this.session);
|
|
354
357
|
}
|
|
355
358
|
|
|
356
359
|
get description(): string {
|
package/src/eval/py/executor.ts
CHANGED
|
@@ -35,6 +35,8 @@ export interface PythonExecutorOptions {
|
|
|
35
35
|
kernelOwnerId?: string;
|
|
36
36
|
/** Kernel mode (session reuse vs per-call) */
|
|
37
37
|
kernelMode?: PythonKernelMode;
|
|
38
|
+
/** Called when a retained session kernel is acquired or replaced. */
|
|
39
|
+
onKernelStart?: (kernelInstanceId: string) => void;
|
|
38
40
|
/** Restart the kernel before executing */
|
|
39
41
|
reset?: boolean;
|
|
40
42
|
/** Session file path for accessing task outputs */
|
|
@@ -107,6 +109,7 @@ export interface PythonResult {
|
|
|
107
109
|
interface PythonSession {
|
|
108
110
|
sessionId: string;
|
|
109
111
|
kernel: PythonKernel;
|
|
112
|
+
kernelInstanceId: string;
|
|
110
113
|
bridgeCapability?: string;
|
|
111
114
|
ownerIds: Set<string>;
|
|
112
115
|
hasFallbackOwner: boolean;
|
|
@@ -365,6 +368,7 @@ async function acquireSession(sessionId: string, cwd: string, options: PythonExe
|
|
|
365
368
|
const session: PythonSession = {
|
|
366
369
|
sessionId,
|
|
367
370
|
kernel,
|
|
371
|
+
kernelInstanceId: crypto.randomUUID(),
|
|
368
372
|
bridgeCapability: options.bridge?.capability,
|
|
369
373
|
ownerIds: new Set(),
|
|
370
374
|
hasFallbackOwner: false,
|
|
@@ -447,6 +451,7 @@ async function replaceSessionKernel(
|
|
|
447
451
|
throw new PythonExecutionCancelledError(false);
|
|
448
452
|
}
|
|
449
453
|
session.kernel = next;
|
|
454
|
+
session.kernelInstanceId = crypto.randomUUID();
|
|
450
455
|
session.bridgeCapability = nextCapability;
|
|
451
456
|
} catch (err) {
|
|
452
457
|
await next?.shutdown().catch(() => undefined);
|
|
@@ -716,6 +721,7 @@ async function executeOnSession(code: string, cwd: string, options: PythonExecut
|
|
|
716
721
|
if (options.bridge && session.bridgeCapability) {
|
|
717
722
|
options.bridge.capability = session.bridgeCapability;
|
|
718
723
|
}
|
|
724
|
+
options.onKernelStart?.(session.kernelInstanceId);
|
|
719
725
|
return await runQueued(session, options, async () => {
|
|
720
726
|
if (options.signal?.aborted) {
|
|
721
727
|
throw new PythonExecutionCancelledError(isTimedOutCancellation(options.signal.reason, options.signal));
|
|
@@ -728,6 +734,7 @@ async function executeOnSession(code: string, cwd: string, options: PythonExecut
|
|
|
728
734
|
if (sessions.get(session.sessionId) !== session) {
|
|
729
735
|
throw new PythonExecutionCancelledError(false);
|
|
730
736
|
}
|
|
737
|
+
options.onKernelStart?.(session.kernelInstanceId);
|
|
731
738
|
}
|
|
732
739
|
try {
|
|
733
740
|
return await executeWithKernel(session.kernel, code, options);
|
|
@@ -742,6 +749,7 @@ async function executeOnSession(code: string, cwd: string, options: PythonExecut
|
|
|
742
749
|
if (sessions.get(session.sessionId) !== session) {
|
|
743
750
|
throw new PythonExecutionCancelledError(false);
|
|
744
751
|
}
|
|
752
|
+
options.onKernelStart?.(session.kernelInstanceId);
|
|
745
753
|
return await executeWithKernel(session.kernel, code, options);
|
|
746
754
|
}
|
|
747
755
|
});
|