@gajae-code/coding-agent 0.18.11 → 0.19.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 +760 -0
- package/dist/types/async/job-manager.d.ts +7 -3
- package/dist/types/async/result-formatting.d.ts +2 -0
- package/dist/types/autoresearch/git.d.ts +1 -1
- package/dist/types/capability/fs.d.ts +2 -2
- package/dist/types/capability/rule.d.ts +7 -2
- package/dist/types/cli/accounts-cli.d.ts +2 -2
- package/dist/types/cli/append-system-prompt.d.ts +6 -0
- package/dist/types/cli/args.d.ts +7 -2
- package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
- package/dist/types/cli/customize-doctor.d.ts +4 -3
- package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
- package/dist/types/cli/install-activation.d.ts +10 -4
- package/dist/types/cli/public-command-errors.d.ts +2 -0
- package/dist/types/cli/root-flags.d.ts +0 -12
- package/dist/types/cli/update-cli.d.ts +21 -3
- package/dist/types/cli-main.d.ts +0 -6
- package/dist/types/cli-ordinary.d.ts +2 -2
- package/dist/types/commands/accounts.d.ts +2 -1
- package/dist/types/commands/launch.d.ts +0 -6
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +13 -0
- package/dist/types/commit/changelog/index.d.ts +1 -0
- package/dist/types/commit/map-reduce/index.d.ts +4 -4
- package/dist/types/config/autorouting-tier-map.d.ts +53 -1
- package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
- package/dist/types/config/config-hot-reload.d.ts +44 -0
- package/dist/types/config/file-lock.d.ts +52 -3
- package/dist/types/config/model-discovery-manager.d.ts +2 -0
- package/dist/types/config/model-profile-activation.d.ts +79 -9
- package/dist/types/config/model-registry.d.ts +72 -8
- package/dist/types/config/model-resolver.d.ts +7 -4
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +57 -4
- package/dist/types/config/settings.d.ts +33 -1
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/customization/import.d.ts +2 -0
- package/dist/types/customization/types.d.ts +1 -1
- package/dist/types/dap/config.d.ts +8 -4
- package/dist/types/dap/session.d.ts +11 -2
- package/dist/types/debug/system-info.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +7 -2
- package/dist/types/discovery/mcp-compat.d.ts +3 -1
- package/dist/types/edit/index.d.ts +5 -0
- package/dist/types/edit/modes/patch.d.ts +14 -0
- package/dist/types/edit/modes/replace.d.ts +3 -0
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +12 -0
- package/dist/types/export/ttsr.d.ts +19 -0
- package/dist/types/extensibility/extensions/types.d.ts +5 -1
- package/dist/types/extensibility/slash-commands.d.ts +1 -0
- package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/content.d.ts +5 -6
- package/dist/types/internal-urls/types.d.ts +2 -0
- package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
- package/dist/types/main.d.ts +23 -18
- package/dist/types/migrate/action-planner.d.ts +10 -1
- package/dist/types/migrate/adapters/codex.d.ts +2 -1
- package/dist/types/migrate/adapters/index.d.ts +42 -1
- package/dist/types/migrate/executor.d.ts +3 -1
- package/dist/types/migrate/hook-module.d.ts +23 -0
- package/dist/types/migrate/report.d.ts +2 -1
- package/dist/types/migrate/types.d.ts +82 -3
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +43 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
- package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/utils/host-status.d.ts +15 -11
- package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
- package/dist/types/runtime-mcp/manager.d.ts +7 -0
- package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
- package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
- package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
- package/dist/types/sdk/broker/broker-exit.d.ts +3 -3
- package/dist/types/sdk/broker/broker.d.ts +29 -2
- package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
- package/dist/types/sdk/broker/ensure.d.ts +141 -9
- package/dist/types/sdk/broker/hop.d.ts +45 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
- package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
- package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
- package/dist/types/sdk/broker/session-index.d.ts +6 -1
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +44 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
- package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
- package/dist/types/sdk/cli/session-cli.d.ts +0 -1
- package/dist/types/sdk/host/control/operations.d.ts +5 -1
- package/dist/types/sdk/host/events.d.ts +4 -0
- package/dist/types/sdk/host/host.d.ts +2 -1
- package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
- package/dist/types/sdk/host/session-runtime.d.ts +40 -8
- package/dist/types/sdk/host/surface-policy.d.ts +2 -1
- package/dist/types/sdk/lifecycle/service.d.ts +12 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +11 -4
- package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
- package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
- package/dist/types/sdk/session-list.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +107 -9
- package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
- package/dist/types/session/messages.d.ts +5 -1
- package/dist/types/session/session-manager.d.ts +29 -3
- package/dist/types/session/startup-auth-config.d.ts +24 -2
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/session/terminal-abort.d.ts +3 -1
- package/dist/types/session-import/service.d.ts +1 -1
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +20 -4
- package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
- package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
- package/dist/types/ssh/ssh-executor.d.ts +8 -1
- package/dist/types/system-prompt.d.ts +3 -2
- package/dist/types/task/executor.d.ts +19 -2
- package/dist/types/task/role-body.d.ts +11 -0
- package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
- package/dist/types/tools/atomic-file-write.d.ts +9 -7
- package/dist/types/tools/awaiting-input.d.ts +28 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +17 -0
- package/dist/types/tools/bash-skill-urls.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +7 -0
- package/dist/types/tools/descriptors.d.ts +15 -2
- package/dist/types/tools/fetch.d.ts +7 -1
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/irc.d.ts +5 -3
- package/dist/types/tools/python.d.ts +1 -1
- package/dist/types/tools/report-issue.d.ts +41 -0
- package/dist/types/tools/subagent.d.ts +23 -0
- package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/file-mentions.d.ts +5 -0
- package/dist/types/utils/image-limits.d.ts +7 -0
- package/dist/types/utils/image-loading.d.ts +0 -1
- package/dist/types/utils/open.d.ts +0 -1
- package/dist/types/utils/pasted-image-loading.d.ts +1 -5
- package/dist/types/utils/prompt-suggestion.d.ts +2 -2
- package/dist/types/utils/shell-snapshot.d.ts +2 -0
- package/dist/types/utils/title-generator.d.ts +13 -3
- package/dist/types/web/scrapers/types.d.ts +8 -1
- package/dist/types/web/search/providers/codex.d.ts +6 -7
- package/dist/types/web/search/providers/insane.d.ts +7 -1
- package/dist/types/web/search/providers/searxng.d.ts +5 -0
- package/package.json +10 -9
- package/scripts/acp-conformance-agent.ts +12 -2
- package/scripts/build-binary.ts +2 -1
- package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
- package/scripts/generate-docs-index.ts +8 -1
- package/scripts/generate-sdk-operation-inventory.ts +38 -4
- package/src/async/job-manager.ts +356 -56
- package/src/async/result-formatting.ts +40 -0
- package/src/autoresearch/git.ts +9 -2
- package/src/autoresearch/prompts/prompt-setup.md +1 -1
- package/src/capability/fs.ts +58 -22
- package/src/capability/index.ts +2 -2
- package/src/capability/rule.ts +11 -2
- package/src/cli/accounts-cli.ts +176 -8
- package/src/cli/append-system-prompt.ts +12 -0
- package/src/cli/args.ts +11 -7
- package/src/cli/auth-broker-cli.ts +21 -11
- package/src/cli/customize-doctor-precedence.ts +31 -0
- package/src/cli/customize-doctor.ts +49 -39
- package/src/cli/doctor/install-repairs.ts +35 -5
- package/src/cli/fast-help.ts +1 -3
- package/src/cli/install-activation.ts +47 -4
- package/src/cli/migrate-cli.ts +19 -6
- package/src/cli/public-command-errors.ts +6 -0
- package/src/cli/root-flags.ts +2 -4
- package/src/cli/stats-cli.ts +9 -5
- package/src/cli/update-cli.ts +471 -13
- package/src/cli-ordinary.ts +7 -2
- package/src/commands/accounts.ts +10 -5
- package/src/commands/harness.ts +25 -15
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +277 -50
- package/src/commands/ultragoal.ts +16 -8
- package/src/commit/agentic/agent.ts +6 -6
- package/src/commit/analysis/conventional.ts +14 -5
- package/src/commit/changelog/index.ts +39 -1
- package/src/commit/map-reduce/index.ts +7 -7
- package/src/commit/message.ts +10 -3
- package/src/commit/pipeline.ts +12 -12
- package/src/config/autorouting-tier-map.ts +50 -1
- package/src/config/config-file.ts +106 -3
- package/src/config/config-hot-reload-trust.ts +148 -0
- package/src/config/config-hot-reload.ts +742 -0
- package/src/config/file-lock.ts +1615 -328
- package/src/config/keybindings.ts +154 -7
- package/src/config/model-bindings-applier.ts +85 -47
- package/src/config/model-discovery-manager.ts +10 -0
- package/src/config/model-profile-activation.ts +889 -148
- package/src/config/model-registry.ts +1706 -205
- package/src/config/model-resolver.ts +52 -22
- package/src/config/models-config-schema.ts +6 -0
- package/src/config/settings-schema.ts +73 -4
- package/src/config/settings.ts +460 -24
- package/src/coordinator-mcp/policy.ts +26 -1
- package/src/coordinator-mcp/server.ts +37 -2
- package/src/crash/sanitize.ts +7 -1
- package/src/customization/import.ts +279 -8
- package/src/customization/inventory.ts +24 -8
- package/src/customization/types.ts +1 -0
- package/src/dap/client.ts +3 -2
- package/src/dap/config.ts +31 -11
- package/src/dap/defaults.json +1 -1
- package/src/dap/session.ts +161 -36
- package/src/debug/crash-diagnostics.ts +89 -6
- package/src/debug/report-bundle.ts +90 -2
- package/src/debug/system-info.ts +8 -3
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/builtin.ts +4 -3
- package/src/discovery/helpers.ts +25 -16
- package/src/discovery/mcp-compat.ts +120 -17
- package/src/edit/apply-patch/index.ts +12 -1
- package/src/edit/index.ts +204 -22
- package/src/edit/modes/patch.ts +214 -8
- package/src/edit/modes/replace.ts +136 -0
- package/src/eval/js/context-manager.ts +29 -3
- package/src/eval/js/worker-entry.ts +51 -18
- package/src/eval/py/executor.ts +14 -4
- package/src/eval/py/runner.py +144 -5
- package/src/eval/py/runtime.ts +44 -4
- package/src/exec/bash-executor.ts +81 -4
- package/src/exec/bash-shell-guardian.ts +4 -1
- package/src/exec/bash-shell-supervisor.ts +8 -4
- package/src/exec/isolated-shell.ts +5 -1
- package/src/exec/non-interactive-env.ts +0 -1
- package/src/export/html/index.ts +86 -6
- package/src/export/ttsr.ts +176 -1
- package/src/extensibility/custom-tools/wrapper.ts +3 -1
- package/src/extensibility/extensions/loader.ts +10 -1
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
- package/src/extensibility/extensions/types.ts +5 -1
- package/src/extensibility/hooks/loader.ts +10 -2
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
- package/src/extensibility/plugins/marketplace/manager.ts +36 -10
- package/src/extensibility/slash-commands.ts +5 -0
- package/src/gjc-runtime/gc-runtime.ts +37 -7
- package/src/gjc-runtime/launch-tmux.ts +30 -15
- package/src/gjc-runtime/launch-worktree.test.ts +148 -0
- package/src/gjc-runtime/launch-worktree.ts +101 -14
- package/src/gjc-runtime/managed-owner-admission.ts +46 -2
- package/src/gjc-runtime/ralplan-current-final.ts +294 -0
- package/src/gjc-runtime/ralplan-runtime.ts +95 -1
- package/src/gjc-runtime/session-resolution.ts +38 -6
- package/src/gjc-runtime/session-state-lock.ts +59 -14
- package/src/gjc-runtime/state-runtime.ts +23 -19
- package/src/gjc-runtime/state-writer.ts +109 -5
- package/src/gjc-runtime/tmux-sessions.ts +93 -13
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
- package/src/gjc-runtime/ultragoal-guard.ts +9 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
- package/src/harness-control-plane/finalize.ts +11 -0
- package/src/harness-control-plane/receipt-spool.ts +105 -28
- package/src/harness-control-plane/storage.ts +124 -6
- package/src/hindsight/content.ts +116 -16
- package/src/hindsight/mental-models.ts +22 -10
- package/src/hindsight/state.ts +7 -4
- package/src/hooks/native-skill-hook.ts +17 -12
- package/src/internal-urls/artifact-protocol.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +23 -22
- package/src/internal-urls/local-protocol.ts +167 -8
- package/src/internal-urls/types.ts +2 -0
- package/src/lsp/client.ts +2 -1
- package/src/lsp/clients/biome-client.ts +2 -0
- package/src/lsp/clients/swiftlint-client.ts +2 -0
- package/src/lsp/index.ts +29 -0
- package/src/lsp/workspace-path.ts +23 -0
- package/src/main.ts +330 -92
- package/src/memories/index.ts +25 -2
- package/src/migrate/action-planner.ts +574 -2
- package/src/migrate/adapters/claude-code.ts +162 -5
- package/src/migrate/adapters/codex.ts +77 -7
- package/src/migrate/adapters/index.ts +258 -5
- package/src/migrate/adapters/opencode.ts +10 -1
- package/src/migrate/executor.ts +222 -7
- package/src/migrate/hook-module.ts +193 -0
- package/src/migrate/report.ts +63 -2
- package/src/migrate/types.ts +84 -4
- package/src/modes/DESIGN.md +51 -0
- package/src/modes/acp/acp-agent.ts +10 -1
- package/src/modes/acp/permission-mode.ts +18 -1
- package/src/modes/components/agent-dashboard.ts +20 -4
- package/src/modes/components/assistant-message.ts +55 -1
- package/src/modes/components/customization/customization-dashboard.ts +7 -0
- package/src/modes/components/customization/import-wizard.ts +29 -3
- package/src/modes/components/model-selector.ts +157 -103
- package/src/modes/components/settings-selector.ts +103 -37
- package/src/modes/components/welcome.ts +3 -1
- package/src/modes/controllers/command-controller.ts +300 -9
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +31 -1
- package/src/modes/controllers/goal-mode-controller.ts +79 -10
- package/src/modes/controllers/input-controller.ts +2 -0
- package/src/modes/controllers/plan-mode-controller.ts +66 -11
- package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
- package/src/modes/controllers/selector-controller.ts +76 -7
- package/src/modes/interactive-mode.ts +123 -4
- package/src/modes/prompt-suggestion-controller.ts +1 -1
- package/src/modes/runtime-init.ts +5 -1
- package/src/modes/theme/theme.ts +15 -0
- package/src/modes/utils/host-status.ts +21 -10
- package/src/prompts/agent-fragments/browser-aside.md +2 -2
- package/src/prompts/system/irc-incoming.md +3 -1
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/irc.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/report-issue.md +13 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-credential-selector.ts +2 -2
- package/src/runtime-mcp/content-limits.ts +7 -0
- package/src/runtime-mcp/manager-pool.test.ts +5 -4
- package/src/runtime-mcp/manager.ts +40 -3
- package/src/runtime-mcp/oauth-flow.ts +32 -6
- package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
- package/src/runtime-mcp/project-host-values.ts +12 -8
- package/src/runtime-mcp/render.ts +16 -1
- package/src/runtime-mcp/tool-bridge.ts +194 -21
- package/src/runtime-mcp/transports/stdio.ts +2 -1
- package/src/sdk/broker/broker-exit.ts +10 -5
- package/src/sdk/broker/broker.ts +484 -85
- package/src/sdk/broker/daemon-entry.ts +338 -116
- package/src/sdk/broker/doctor-restart.ts +2 -1
- package/src/sdk/broker/ensure.ts +1214 -268
- package/src/sdk/broker/hop.ts +286 -0
- package/src/sdk/broker/lifecycle-ledger.ts +38 -11
- package/src/sdk/broker/lifecycle.ts +102 -6
- package/src/sdk/broker/lock-host-identity.ts +29 -0
- package/src/sdk/broker/session-index.ts +91 -16
- package/src/sdk/broker/transport.ts +17 -1
- package/src/sdk/bus/chat-command-policy.ts +16 -3
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +460 -35
- package/src/sdk/bus/reconciliation-store.ts +201 -8
- package/src/sdk/bus/session-control.ts +2 -0
- package/src/sdk/bus/slack-daemon.ts +105 -9
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -2
- package/src/sdk/bus/threaded-render.ts +20 -1
- package/src/sdk/cli/session-cli.ts +23 -6
- package/src/sdk/host/control/dispatch.ts +13 -1
- package/src/sdk/host/control/operations.ts +10 -1
- package/src/sdk/host/events.ts +67 -4
- package/src/sdk/host/host.ts +8 -2
- package/src/sdk/host/prompt-image-upload.ts +438 -0
- package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
- package/src/sdk/host/session-runtime.test.ts +1737 -129
- package/src/sdk/host/session-runtime.ts +684 -83
- package/src/sdk/host/surface-policy.ts +4 -0
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
- package/src/sdk/host/websocket-transport.ts +19 -7
- package/src/sdk/lifecycle/service.ts +15 -1
- package/src/sdk/prompt-deadline-flush.ts +78 -5
- package/src/sdk/prompt-deadline-manager.ts +68 -14
- package/src/sdk/prompt-status.ts +6 -4
- package/src/sdk/protocol/adapter-validation.ts +81 -12
- package/src/sdk/protocol/operation-inventory.generated.json +261 -2
- package/src/sdk/protocol/operation-registry.ts +33 -3
- package/src/sdk/reconciliation-extensions.ts +1 -0
- package/src/sdk/session-list.ts +1 -0
- package/src/sdk/session.ts +237 -97
- package/src/session/agent-session.ts +2726 -479
- package/src/session/history-storage.ts +182 -12
- package/src/session/internal/managed-session-scope.ts +173 -57
- package/src/session/internal/managed-session-storage.ts +85 -12
- package/src/session/internal/native-publish-outcome.ts +5 -1
- package/src/session/messages.ts +47 -6
- package/src/session/session-manager.ts +326 -19
- package/src/session/startup-auth-config.ts +116 -8
- package/src/session/streaming-output.ts +262 -4
- package/src/session/terminal-abort.ts +14 -2
- package/src/session-import/redact.ts +53 -2
- package/src/session-import/service.ts +1 -0
- package/src/skill-state/workflow-mutation-guard.ts +2145 -206
- package/src/slash-commands/builtin-registry.ts +21 -6
- package/src/slash-commands/helpers/credential-switch.ts +10 -5
- package/src/slash-commands/helpers/mcp.ts +11 -3
- package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
- package/src/ssh/ssh-executor.ts +9 -2
- package/src/stt/recorder.ts +26 -9
- package/src/system-prompt.ts +61 -16
- package/src/task/executor.ts +115 -20
- package/src/task/index.ts +389 -175
- package/src/task/role-body.ts +84 -0
- package/src/task/token-log-mode.test.ts +162 -0
- package/src/task/token-log.ts +91 -2
- package/src/tools/archive-reader.ts +650 -37
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit-write-path.ts +64 -0
- package/src/tools/ast-edit.ts +18 -1
- package/src/tools/ast-grep.ts +7 -2
- package/src/tools/atomic-file-write.ts +46 -15
- package/src/tools/auto-generated-guard.ts +15 -3
- package/src/tools/awaiting-input.ts +114 -0
- package/src/tools/bash-allowed-prefixes.ts +214 -6
- package/src/tools/bash-interactive.ts +14 -2
- package/src/tools/bash-skill-urls.ts +58 -5
- package/src/tools/bash.ts +113 -26
- package/src/tools/browser/tab-worker.ts +39 -13
- package/src/tools/browser.ts +17 -7
- package/src/tools/cron.ts +10 -1
- package/src/tools/debug.ts +16 -8
- package/src/tools/descriptors.test.ts +44 -0
- package/src/tools/descriptors.ts +50 -6
- package/src/tools/eval.ts +15 -0
- package/src/tools/fetch.ts +93 -4
- package/src/tools/gh.ts +27 -12
- package/src/tools/image-gen.ts +20 -6
- package/src/tools/index.ts +2 -0
- package/src/tools/irc.ts +5 -3
- package/src/tools/monitor.ts +9 -1
- package/src/tools/output-meta.ts +74 -5
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +26 -37
- package/src/tools/recipe/runner.ts +23 -12
- package/src/tools/render-utils.ts +2 -2
- package/src/tools/report-issue.ts +184 -0
- package/src/tools/search.ts +3 -2
- package/src/tools/ssh.ts +274 -8
- package/src/tools/subagent-render.ts +114 -12
- package/src/tools/subagent.ts +118 -5
- package/src/tools/tmux-self-injection-guard.ts +3301 -122
- package/src/tools/todo-write.ts +41 -3
- package/src/tools/tool-catalog.generated.ts +32 -4
- package/src/tools/ultragoal-ask-guard.ts +13 -1
- package/src/tools/write.ts +42 -3
- package/src/tui/tree-list.ts +15 -1
- package/src/utils/commit-message-generator.ts +12 -4
- package/src/utils/external-editor.ts +21 -7
- package/src/utils/file-mentions.ts +75 -7
- package/src/utils/git.ts +38 -7
- package/src/utils/image-limits.ts +8 -0
- package/src/utils/image-loading.ts +1 -1
- package/src/utils/open.ts +73 -4
- package/src/utils/pasted-image-loading.ts +9 -8
- package/src/utils/prompt-suggestion.ts +5 -4
- package/src/utils/shell-snapshot.ts +9 -1
- package/src/utils/title-generator.ts +72 -22
- package/src/web/scrapers/index.ts +3 -1
- package/src/web/scrapers/types.ts +8 -0
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/index.ts +2 -1
- package/src/web/search/providers/codex.ts +29 -32
- package/src/web/search/providers/insane.ts +91 -28
- package/src/web/search/providers/searxng.ts +62 -10
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keep a subagent role body inside the host [ROLE] block.
|
|
3
|
+
*
|
|
4
|
+
* The body is the agent instruction. It is inserted between host [ROLE] and
|
|
5
|
+
* [/ROLE]. A literal framing tag would end that block early. Only the four
|
|
6
|
+
* host framing names are rewritten; other brackets stay literal.
|
|
7
|
+
*
|
|
8
|
+
* One left-to-right scan: a gap run, a slash only when it is present, then
|
|
9
|
+
* one more gap run, then the word. A non-matching "[" does not hide a later tag.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const WORDS = ["completion", "context", "role", "coop"] as const;
|
|
13
|
+
|
|
14
|
+
function isGap(code: number): boolean {
|
|
15
|
+
return (
|
|
16
|
+
code === 0x09 ||
|
|
17
|
+
code === 0x0a ||
|
|
18
|
+
code === 0x0b ||
|
|
19
|
+
code === 0x0c ||
|
|
20
|
+
code === 0x0d ||
|
|
21
|
+
code === 0x20 ||
|
|
22
|
+
code === 0xa0 ||
|
|
23
|
+
code === 0x200b ||
|
|
24
|
+
code === 0x200c ||
|
|
25
|
+
code === 0x200d ||
|
|
26
|
+
code === 0x1680 ||
|
|
27
|
+
(code >= 0x2000 && code <= 0x200a) ||
|
|
28
|
+
code === 0x2028 ||
|
|
29
|
+
code === 0x2029 ||
|
|
30
|
+
code === 0x202f ||
|
|
31
|
+
code === 0x205f ||
|
|
32
|
+
code === 0x3000 ||
|
|
33
|
+
code === 0xfeff
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function wordLengthAt(body: string, index: number): number {
|
|
38
|
+
const slice = body.slice(index, index + 10).toLowerCase();
|
|
39
|
+
for (const word of WORDS) {
|
|
40
|
+
if (!slice.startsWith(word)) continue;
|
|
41
|
+
const after = body.charCodeAt(index + word.length);
|
|
42
|
+
if (Number.isNaN(after) || isGap(after) || after === 0x5d) return word.length;
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** End index of a framing tag starting at "[", or -1. */
|
|
48
|
+
function framingTagEnd(body: string, start: number): number {
|
|
49
|
+
let index = start + 1;
|
|
50
|
+
while (index < body.length && isGap(body.charCodeAt(index))) index++;
|
|
51
|
+
if (body.charCodeAt(index) === 0x2f) {
|
|
52
|
+
index++;
|
|
53
|
+
while (index < body.length && isGap(body.charCodeAt(index))) index++;
|
|
54
|
+
}
|
|
55
|
+
const wordLength = wordLengthAt(body, index);
|
|
56
|
+
if (wordLength === 0) return -1;
|
|
57
|
+
index += wordLength;
|
|
58
|
+
while (index < body.length && isGap(body.charCodeAt(index))) index++;
|
|
59
|
+
return body.charCodeAt(index) === 0x5d ? index + 1 : -1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function containSubagentRoleBody(body: string): string {
|
|
63
|
+
const parts: string[] = [];
|
|
64
|
+
let plainStart = 0;
|
|
65
|
+
let index = 0;
|
|
66
|
+
while (index < body.length) {
|
|
67
|
+
if (body.charCodeAt(index) !== 0x5b) {
|
|
68
|
+
index++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const end = framingTagEnd(body, index);
|
|
72
|
+
if (end < 0) {
|
|
73
|
+
index++;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (plainStart < index) parts.push(body.slice(plainStart, index));
|
|
77
|
+
parts.push(body.slice(index, end).replaceAll("[", "[").replaceAll("]", "]"));
|
|
78
|
+
index = end;
|
|
79
|
+
plainStart = index;
|
|
80
|
+
}
|
|
81
|
+
if (plainStart === 0) return body;
|
|
82
|
+
if (plainStart < body.length) parts.push(body.slice(plainStart));
|
|
83
|
+
return parts.join("");
|
|
84
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { afterAll, describe, expect, it } from "bun:test";
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { persistTaskTokenLog, taskTokenLogFromChat } from "./token-log";
|
|
6
|
+
|
|
7
|
+
// Mode bits and final-component symlinks are POSIX. Windows ACLs are out of scope.
|
|
8
|
+
const skipPosix = process.platform === "win32";
|
|
9
|
+
const skipOwnerReadOnly = skipPosix || process.getuid?.() === 0;
|
|
10
|
+
const tempRoots: string[] = [];
|
|
11
|
+
|
|
12
|
+
async function tempDir(): Promise<string> {
|
|
13
|
+
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "gjc-token-log-mode-"));
|
|
14
|
+
tempRoots.push(dir);
|
|
15
|
+
return dir;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
afterAll(async () => {
|
|
19
|
+
await Promise.all(tempRoots.splice(0).map(dir => fs.rm(dir, { recursive: true, force: true })));
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
function entry(id: string) {
|
|
23
|
+
return taskTokenLogFromChat(
|
|
24
|
+
{ inputTokens: 1, outputTokens: 2, cachedInputTokens: 0, cacheWriteTokens: 0 },
|
|
25
|
+
{ subagentId: id, turn: 1, at: "2026-01-01T00:00:00.000Z" },
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function modeOf(filePath: string): Promise<number> {
|
|
30
|
+
return (await fs.lstat(filePath)).mode & 0o777;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe("task token log mode", () => {
|
|
34
|
+
it.skipIf(skipPosix)("refuses a symlink token-log.jsonl", async () => {
|
|
35
|
+
const root = await tempDir();
|
|
36
|
+
const outside = path.join(root, "outside.jsonl");
|
|
37
|
+
await fs.writeFile(outside, "kept");
|
|
38
|
+
const dir = path.join(root, "logs");
|
|
39
|
+
await fs.mkdir(dir);
|
|
40
|
+
const link = path.join(dir, "token-log.jsonl");
|
|
41
|
+
await fs.symlink(outside, link);
|
|
42
|
+
|
|
43
|
+
await expect(persistTaskTokenLog(entry("root"), { dir })).rejects.toThrow(/not a regular file/);
|
|
44
|
+
expect(await fs.readFile(outside, "utf8")).toBe("kept");
|
|
45
|
+
expect((await fs.lstat(link)).isSymbolicLink()).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it.skipIf(skipPosix)("refuses a symlink token-log directory", async () => {
|
|
49
|
+
const root = await tempDir();
|
|
50
|
+
const outside = path.join(root, "outside");
|
|
51
|
+
await fs.mkdir(outside);
|
|
52
|
+
const dir = path.join(root, "token-logs");
|
|
53
|
+
await fs.symlink(outside, dir);
|
|
54
|
+
|
|
55
|
+
await expect(persistTaskTokenLog(entry("root"), { dir })).rejects.toThrow(/not a directory/);
|
|
56
|
+
expect(await fs.readdir(outside)).toEqual([]);
|
|
57
|
+
expect((await fs.lstat(dir)).isSymbolicLink()).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it.skipIf(skipPosix)("creates a token log as mode 0600 under a permissive umask", async () => {
|
|
61
|
+
const previous = process.umask(0);
|
|
62
|
+
try {
|
|
63
|
+
const root = await tempDir();
|
|
64
|
+
const dir = path.join(root, "logs");
|
|
65
|
+
await persistTaskTokenLog(entry("root"), { dir });
|
|
66
|
+
expect(await modeOf(dir)).toBe(0o700);
|
|
67
|
+
expect(await modeOf(path.join(dir, "token-log.jsonl"))).toBe(0o600);
|
|
68
|
+
} finally {
|
|
69
|
+
process.umask(previous);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it.skipIf(skipPosix)("tightens an existing mode 0666 token log to 0600", async () => {
|
|
74
|
+
const root = await tempDir();
|
|
75
|
+
const dir = path.join(root, "logs");
|
|
76
|
+
await fs.mkdir(dir, { mode: 0o700 });
|
|
77
|
+
const file = path.join(dir, "token-log.jsonl");
|
|
78
|
+
await fs.writeFile(file, "", { mode: 0o666 });
|
|
79
|
+
await fs.chmod(file, 0o666);
|
|
80
|
+
|
|
81
|
+
await persistTaskTokenLog(entry("root"), { dir });
|
|
82
|
+
|
|
83
|
+
expect(await modeOf(file)).toBe(0o600);
|
|
84
|
+
expect(await fs.readFile(file, "utf8")).toContain('"subagentId":"root"');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it.skipIf(skipPosix)("tightens an existing mode 0777 token-log directory to 0700", async () => {
|
|
88
|
+
const root = await tempDir();
|
|
89
|
+
const dir = path.join(root, "logs");
|
|
90
|
+
await fs.mkdir(dir, { mode: 0o777 });
|
|
91
|
+
await fs.chmod(dir, 0o777);
|
|
92
|
+
|
|
93
|
+
await persistTaskTokenLog(entry("root"), { dir });
|
|
94
|
+
|
|
95
|
+
expect(await modeOf(dir)).toBe(0o700);
|
|
96
|
+
expect(await modeOf(path.join(dir, "token-log.jsonl"))).toBe(0o600);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("still allows a second append to a regular token log", async () => {
|
|
100
|
+
const root = await tempDir();
|
|
101
|
+
const dir = path.join(root, "logs");
|
|
102
|
+
await persistTaskTokenLog(entry("one"), { dir });
|
|
103
|
+
await persistTaskTokenLog(entry("two"), { dir });
|
|
104
|
+
const text = await fs.readFile(path.join(dir, "token-log.jsonl"), "utf8");
|
|
105
|
+
expect(text).toContain('"subagentId":"one"');
|
|
106
|
+
expect(text).toContain('"subagentId":"two"');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it.skipIf(skipPosix)("still allows a token log through a symlinked parent", async () => {
|
|
110
|
+
const root = await tempDir();
|
|
111
|
+
const realParent = path.join(root, "real");
|
|
112
|
+
await fs.mkdir(realParent);
|
|
113
|
+
const via = path.join(root, "via");
|
|
114
|
+
await fs.symlink(realParent, via);
|
|
115
|
+
const dir = path.join(via, "token-logs");
|
|
116
|
+
|
|
117
|
+
await persistTaskTokenLog(entry("via"), { dir });
|
|
118
|
+
|
|
119
|
+
expect(await fs.readFile(path.join(realParent, "token-logs", "token-log.jsonl"), "utf8")).toContain(
|
|
120
|
+
'"subagentId":"via"',
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it.skipIf(skipPosix)("keeps owner mode 0600 when appending a token log", async () => {
|
|
125
|
+
const root = await tempDir();
|
|
126
|
+
const dir = path.join(root, "logs");
|
|
127
|
+
await fs.mkdir(dir, { mode: 0o700 });
|
|
128
|
+
const file = path.join(dir, "token-log.jsonl");
|
|
129
|
+
await fs.writeFile(file, "", { mode: 0o600 });
|
|
130
|
+
|
|
131
|
+
await persistTaskTokenLog(entry("root"), { dir });
|
|
132
|
+
|
|
133
|
+
expect(await modeOf(file)).toBe(0o600);
|
|
134
|
+
expect(await fs.readFile(file, "utf8")).toContain('"subagentId":"root"');
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it.skipIf(skipOwnerReadOnly)("still allows a token log in a mode 0300 directory", async () => {
|
|
138
|
+
const root = await tempDir();
|
|
139
|
+
const dir = path.join(root, "logs");
|
|
140
|
+
await fs.mkdir(dir, { mode: 0o700 });
|
|
141
|
+
await fs.chmod(dir, 0o300);
|
|
142
|
+
try {
|
|
143
|
+
await persistTaskTokenLog(entry("root"), { dir });
|
|
144
|
+
expect(await fs.readFile(path.join(dir, "token-log.jsonl"), "utf8")).toContain('"subagentId":"root"');
|
|
145
|
+
} finally {
|
|
146
|
+
await fs.chmod(dir, 0o700);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it.skipIf(skipOwnerReadOnly)("leaves a mode 0400 token log unchanged when the append cannot write", async () => {
|
|
151
|
+
const root = await tempDir();
|
|
152
|
+
const dir = path.join(root, "logs");
|
|
153
|
+
await fs.mkdir(dir, { mode: 0o700 });
|
|
154
|
+
const file = path.join(dir, "token-log.jsonl");
|
|
155
|
+
await fs.writeFile(file, "kept\n", { mode: 0o600 });
|
|
156
|
+
await fs.chmod(file, 0o400);
|
|
157
|
+
|
|
158
|
+
await expect(persistTaskTokenLog(entry("root"), { dir })).rejects.toThrow(/EACCES/);
|
|
159
|
+
expect(await fs.readFile(file, "utf8")).toBe("kept\n");
|
|
160
|
+
expect(await modeOf(file)).toBe(0o400);
|
|
161
|
+
});
|
|
162
|
+
});
|
package/src/task/token-log.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as fsSync from "node:fs";
|
|
1
2
|
import * as fs from "node:fs/promises";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
import type { ChatUsageSnapshot, CostEstimate } from "@gajae-code/agent-core";
|
|
@@ -6,6 +7,7 @@ import { resolveGjcSessionForRead, SessionResolutionError } from "../gjc-runtime
|
|
|
6
7
|
import type { TaskTokenLog, TaskTokenMetrics } from "./types";
|
|
7
8
|
|
|
8
9
|
const TOKEN_LOG_FILE = "token-log.jsonl";
|
|
10
|
+
const NO_FOLLOW = process.platform === "win32" ? 0 : (fsSync.constants.O_NOFOLLOW ?? 0);
|
|
9
11
|
|
|
10
12
|
export interface TaskTokenLogChatBuckets {
|
|
11
13
|
readonly inputTokens: number;
|
|
@@ -92,9 +94,96 @@ export async function resolveTaskTokenLogDir(
|
|
|
92
94
|
throw error;
|
|
93
95
|
}
|
|
94
96
|
}
|
|
97
|
+
function errnoCode(error: unknown): string | undefined {
|
|
98
|
+
return isNodeError(error) ? error.code : undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function sameInode(left: fsSync.BigIntStats, right: fsSync.BigIntStats): boolean {
|
|
102
|
+
return left.dev === right.dev && left.ino === right.ino && left.nlink === right.nlink;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Leaf directory mode 0700. `lstat` plus `chmod` does not need read permission, so a
|
|
107
|
+
* mode 0300 directory stays writable. A symlink leaf is refused before chmod.
|
|
108
|
+
* This does not pin the directory against a later rename in a writable parent.
|
|
109
|
+
*/
|
|
110
|
+
async function ensureOwnerDirectory(dir: string): Promise<void> {
|
|
111
|
+
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
112
|
+
let current: fsSync.Stats;
|
|
113
|
+
try {
|
|
114
|
+
current = await fs.lstat(dir);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
const code = errnoCode(error);
|
|
117
|
+
if (code === "ELOOP" || code === "ENOTDIR") throw new Error("token log directory is not a directory");
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
if (current.isSymbolicLink() || !current.isDirectory()) throw new Error("token log directory is not a directory");
|
|
121
|
+
if (process.platform === "win32" || (current.mode & 0o077) === 0) return;
|
|
122
|
+
await fs.chmod(dir, 0o700);
|
|
123
|
+
const tightened = await fs.lstat(dir);
|
|
124
|
+
if (tightened.isSymbolicLink() || !tightened.isDirectory() || (tightened.mode & 0o777) !== 0o700) {
|
|
125
|
+
throw new Error("token log directory could not be tightened to mode 0700");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Append like the workflow owner-only writer: mode 0600, `O_NOFOLLOW` when the file
|
|
131
|
+
* exists, `O_EXCL` when it does not, and chmod to 0600 when group or other bits are set.
|
|
132
|
+
*/
|
|
133
|
+
async function appendOwnerOnly(filePath: string, text: string): Promise<void> {
|
|
134
|
+
await ensureOwnerDirectory(path.dirname(filePath));
|
|
135
|
+
let handle: fs.FileHandle | undefined;
|
|
136
|
+
let initial: fsSync.BigIntStats | undefined;
|
|
137
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
138
|
+
initial = undefined;
|
|
139
|
+
try {
|
|
140
|
+
initial = await fs.lstat(filePath, { bigint: true });
|
|
141
|
+
if (initial.isSymbolicLink() || !initial.isFile()) throw new Error("token log path is not a regular file");
|
|
142
|
+
} catch (error) {
|
|
143
|
+
if (errnoCode(error) !== "ENOENT") throw error;
|
|
144
|
+
}
|
|
145
|
+
const flags = initial
|
|
146
|
+
? fsSync.constants.O_WRONLY | fsSync.constants.O_APPEND | NO_FOLLOW
|
|
147
|
+
: fsSync.constants.O_WRONLY | fsSync.constants.O_APPEND | fsSync.constants.O_CREAT | fsSync.constants.O_EXCL;
|
|
148
|
+
try {
|
|
149
|
+
handle = await fs.open(filePath, flags, 0o600);
|
|
150
|
+
break;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
const code = errnoCode(error);
|
|
153
|
+
if (code === "ELOOP") throw new Error("token log path is not a regular file");
|
|
154
|
+
if (initial === undefined && code === "EEXIST" && attempt === 0) continue;
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (!handle) throw new Error("token log path identity changed before append");
|
|
159
|
+
try {
|
|
160
|
+
const opened = await handle.stat({ bigint: true });
|
|
161
|
+
const named = await fs.lstat(filePath, { bigint: true });
|
|
162
|
+
if (
|
|
163
|
+
opened.isSymbolicLink() ||
|
|
164
|
+
!opened.isFile() ||
|
|
165
|
+
named.isSymbolicLink() ||
|
|
166
|
+
!named.isFile() ||
|
|
167
|
+
(initial !== undefined && !sameInode(initial, opened)) ||
|
|
168
|
+
!sameInode(opened, named)
|
|
169
|
+
) {
|
|
170
|
+
throw new Error("token log path identity changed before append");
|
|
171
|
+
}
|
|
172
|
+
if (process.platform !== "win32" && (Number(opened.mode) & 0o077) !== 0) {
|
|
173
|
+
await handle.chmod(0o600);
|
|
174
|
+
const tightened = await handle.stat({ bigint: true });
|
|
175
|
+
if ((Number(tightened.mode) & 0o777) !== 0o600) {
|
|
176
|
+
throw new Error("token log path could not be tightened to mode 0600");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
await handle.writeFile(text, "utf8");
|
|
180
|
+
} finally {
|
|
181
|
+
await handle.close();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
95
185
|
export async function persistTaskTokenLog(entry: TaskTokenLog, opts: { dir: string }): Promise<void> {
|
|
96
|
-
await
|
|
97
|
-
await fs.appendFile(path.join(opts.dir, TOKEN_LOG_FILE), `${JSON.stringify(entry)}\n`, "utf-8");
|
|
186
|
+
await appendOwnerOnly(path.join(opts.dir, TOKEN_LOG_FILE), `${JSON.stringify(entry)}\n`);
|
|
98
187
|
}
|
|
99
188
|
|
|
100
189
|
export async function readTaskTokenLogs(dir: string): Promise<TaskTokenLog[]> {
|