@jinn-network/client 0.1.9-canary.5c19fc6d → 0.1.9-canary.5ff3d8cb
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/CONTRIBUTING.md +2 -2
- package/dist/adapters/mech/adapter.d.ts +10 -0
- package/dist/adapters/mech/adapter.js +19 -1
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +1 -88
- package/dist/adapters/mech/types.js +1 -45
- package/dist/adapters/mech/types.js.map +1 -1
- package/dist/api/bootstrap-endpoint.d.ts +18 -3
- package/dist/api/bootstrap-endpoint.js +3 -0
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/gather-status.js +6 -5
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/launcher-endpoints.js +6 -1
- package/dist/api/launcher-endpoints.js.map +1 -1
- package/dist/api/launcher-status.d.ts +2 -0
- package/dist/api/launcher-status.js.map +1 -1
- package/dist/api/launcher-tasks.d.ts +47 -0
- package/dist/api/launcher-tasks.js +88 -3
- package/dist/api/launcher-tasks.js.map +1 -1
- package/dist/api/loop-completion-build.d.ts +2 -2
- package/dist/api/loop-completion-build.js +2 -3
- package/dist/api/loop-completion-build.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +2 -1
- package/dist/api/portfolio-v0-build.js +5 -7
- package/dist/api/portfolio-v0-build.js.map +1 -1
- package/dist/api/prediction-v1-build.d.ts +2 -2
- package/dist/api/prediction-v1-build.js +5 -7
- package/dist/api/prediction-v1-build.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +4 -0
- package/dist/api/setup-endpoints.js +13 -7
- package/dist/api/setup-endpoints.js.map +1 -1
- package/dist/api/status-build.js +1 -4
- package/dist/api/status-build.js.map +1 -1
- package/dist/api/task-run-routing.d.ts +1 -1
- package/dist/api/task-runs-build.d.ts +2 -2
- package/dist/api/task-runs-build.js +5 -7
- package/dist/api/task-runs-build.js.map +1 -1
- package/dist/bin/jinn-distill-mcp.js +813 -0
- package/dist/bin/jinn-layer.js +4992 -1151
- package/dist/build-info.json +4 -4
- package/dist/build-meta.json +1 -1
- package/dist/captures/distil-export.d.ts +54 -0
- package/dist/captures/distil-export.js +135 -0
- package/dist/captures/distil-export.js.map +1 -0
- package/dist/captures/ingest.d.ts +21 -0
- package/dist/captures/ingest.js +144 -0
- package/dist/captures/ingest.js.map +1 -0
- package/dist/captures/live-publisher.js +4 -3
- package/dist/captures/live-publisher.js.map +1 -1
- package/dist/captures/publish.d.ts +4 -0
- package/dist/captures/publish.js +2 -2
- package/dist/captures/publish.js.map +1 -1
- package/dist/cli/execution-context.js +2 -1
- package/dist/cli/execution-context.js.map +1 -1
- package/dist/config.js +34 -1
- package/dist/config.js.map +1 -1
- package/dist/contracts/abis.d.ts +100 -0
- package/dist/contracts/abis.js +58 -0
- package/dist/contracts/abis.js.map +1 -0
- package/dist/contracts/addresses.d.ts +36 -0
- package/dist/contracts/addresses.js +60 -0
- package/dist/contracts/addresses.js.map +1 -0
- package/dist/corpus/onchain-query.d.ts +0 -1
- package/dist/corpus/onchain-query.js +2 -5
- package/dist/corpus/onchain-query.js.map +1 -1
- package/dist/daemon/balance-topup-loop.js +27 -12
- package/dist/daemon/balance-topup-loop.js.map +1 -1
- package/dist/daemon/creator.js +15 -13
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.js +35 -13
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/loop-heartbeat.d.ts +62 -7
- package/dist/daemon/loop-heartbeat.js +50 -13
- package/dist/daemon/loop-heartbeat.js.map +1 -1
- package/dist/{api/peers.js → daemon/peer-sync.js} +2 -2
- package/dist/daemon/peer-sync.js.map +1 -0
- package/dist/daemon/reward-claim-loop.js +27 -12
- package/dist/daemon/reward-claim-loop.js.map +1 -1
- package/dist/daemon/spend-cap-gate.d.ts +0 -6
- package/dist/daemon/spend-cap-gate.js +1 -8
- package/dist/daemon/spend-cap-gate.js.map +1 -1
- package/dist/dashboard/assets/index-BdGCkGPF.js +157 -0
- package/dist/dashboard/assets/index-D7rvJRNa.css +1 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/discovery/http.js +83 -1
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.js +16 -8
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +43 -0
- package/dist/discovery/types.js.map +1 -1
- package/dist/discovery/with-fallback.js +10 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/bootstrap-run.d.ts +25 -0
- package/dist/earning/bootstrap-run.js +315 -0
- package/dist/earning/bootstrap-run.js.map +1 -0
- package/dist/earning/bootstrap.d.ts +6 -11
- package/dist/earning/bootstrap.js +45 -195
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/contracts.d.ts +2 -3
- package/dist/earning/contracts.js +12 -21
- package/dist/earning/contracts.js.map +1 -1
- package/dist/earning/master-gas.d.ts +10 -0
- package/dist/earning/master-gas.js +11 -0
- package/dist/earning/master-gas.js.map +1 -0
- package/dist/earning/safe-adapter.js +1 -45
- package/dist/earning/safe-adapter.js.map +1 -1
- package/dist/earning/steps/context.d.ts +42 -0
- package/dist/earning/steps/context.js +4 -0
- package/dist/earning/steps/context.js.map +1 -0
- package/dist/earning/steps/fleet-identity-register.d.ts +4 -0
- package/dist/earning/steps/fleet-identity-register.js +65 -0
- package/dist/earning/steps/fleet-identity-register.js.map +1 -0
- package/dist/earning/steps/fleet-safe-deploy.d.ts +4 -0
- package/dist/earning/steps/fleet-safe-deploy.js +62 -0
- package/dist/earning/steps/fleet-safe-deploy.js.map +1 -0
- package/dist/earning/steps/fleet-safe-predict.d.ts +4 -0
- package/dist/earning/steps/fleet-safe-predict.js +18 -0
- package/dist/earning/steps/fleet-safe-predict.js.map +1 -0
- package/dist/earning/steps/receipt-parsing.d.ts +12 -0
- package/dist/earning/steps/receipt-parsing.js +71 -0
- package/dist/earning/steps/receipt-parsing.js.map +1 -0
- package/dist/earning/stolas-staking.js +20 -14
- package/dist/earning/stolas-staking.js.map +1 -1
- package/dist/erc8004/addresses.d.ts +6 -5
- package/dist/erc8004/addresses.js +7 -5
- package/dist/erc8004/addresses.js.map +1 -1
- package/dist/erc8004/identity.d.ts +12 -1
- package/dist/erc8004/identity.js +31 -0
- package/dist/erc8004/identity.js.map +1 -1
- package/dist/erc8004/index.d.ts +1 -1
- package/dist/erc8004/index.js +1 -1
- package/dist/erc8004/index.js.map +1 -1
- package/dist/erc8004/reputation.js +16 -12
- package/dist/erc8004/reputation.js.map +1 -1
- package/dist/erc8004/validation.js +5 -4
- package/dist/erc8004/validation.js.map +1 -1
- package/dist/eval/capability-slate.d.ts +54 -0
- package/dist/eval/capability-slate.js +116 -0
- package/dist/eval/capability-slate.js.map +1 -0
- package/dist/eval/capability-stats.d.ts +39 -0
- package/dist/eval/capability-stats.js +123 -0
- package/dist/eval/capability-stats.js.map +1 -0
- package/dist/eval/contested-band.d.ts +18 -0
- package/dist/eval/contested-band.js +19 -0
- package/dist/eval/contested-band.js.map +1 -0
- package/dist/eval/corpus-index.d.ts +21 -0
- package/dist/eval/corpus-index.js +55 -0
- package/dist/eval/corpus-index.js.map +1 -0
- package/dist/eval/disjointness.d.ts +26 -0
- package/dist/eval/disjointness.js +67 -0
- package/dist/eval/disjointness.js.map +1 -0
- package/dist/eval/mcnemar-power.d.ts +14 -0
- package/dist/eval/mcnemar-power.js +40 -0
- package/dist/eval/mcnemar-power.js.map +1 -0
- package/dist/harnesses/engine/engine.d.ts +2 -1
- package/dist/harnesses/engine/engine.js +15 -2
- package/dist/harnesses/engine/engine.js.map +1 -1
- package/dist/harnesses/engine/persistence.d.ts +2 -61
- package/dist/harnesses/engine/persistence.js.map +1 -1
- package/dist/harnesses/impls/_evaluator-base.d.ts +48 -0
- package/dist/harnesses/impls/_evaluator-base.js +35 -0
- package/dist/harnesses/impls/_evaluator-base.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-prediction/index.d.ts +2 -3
- package/dist/harnesses/impls/claude-mcp-prediction/index.js +29 -99
- package/dist/harnesses/impls/claude-mcp-prediction/index.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction/mcp-tools.js +4 -21
- package/dist/harnesses/impls/claude-mcp-prediction/mcp-tools.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction/session-orchestrator.d.ts +2 -0
- package/dist/harnesses/impls/claude-mcp-prediction/session-orchestrator.js +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction/session-orchestrator.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/index.js +30 -79
- package/dist/harnesses/impls/claude-mcp-prediction-apy/index.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/mcp-tools.js +4 -19
- package/dist/harnesses/impls/claude-mcp-prediction-apy/mcp-tools.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/session-orchestrator.d.ts +2 -0
- package/dist/harnesses/impls/claude-mcp-prediction-apy/session-orchestrator.js +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/session-orchestrator.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-shared/mcp-server-script.d.ts +39 -0
- package/dist/harnesses/impls/claude-mcp-shared/mcp-server-script.js +62 -0
- package/dist/harnesses/impls/claude-mcp-shared/mcp-server-script.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-shared/mcp-server.d.ts +40 -0
- package/dist/harnesses/impls/claude-mcp-shared/mcp-server.js +44 -0
- package/dist/harnesses/impls/claude-mcp-shared/mcp-server.js.map +1 -0
- package/dist/harnesses/impls/claude-mcp-shared/single-session-harness.d.ts +56 -0
- package/dist/harnesses/impls/claude-mcp-shared/single-session-harness.js +79 -0
- package/dist/harnesses/impls/claude-mcp-shared/single-session-harness.js.map +1 -0
- package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +3 -1
- package/dist/harnesses/impls/learner/adapters/codex-code.js +39 -4
- package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
- package/dist/harnesses/impls/portfolio-v0-evaluator/index.d.ts +5 -15
- package/dist/harnesses/impls/portfolio-v0-evaluator/index.js +10 -29
- package/dist/harnesses/impls/portfolio-v0-evaluator/index.js.map +1 -1
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.d.ts +5 -15
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js +10 -23
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js.map +1 -1
- package/dist/harnesses/impls/prediction-v0-evaluator/index.d.ts +5 -15
- package/dist/harnesses/impls/prediction-v0-evaluator/index.js +10 -25
- package/dist/harnesses/impls/prediction-v0-evaluator/index.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +8 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
- package/dist/learner/verification-gate.d.ts +53 -0
- package/dist/learner/verification-gate.js +80 -0
- package/dist/learner/verification-gate.js.map +1 -0
- package/dist/main.js +74 -457
- package/dist/main.js.map +1 -1
- package/dist/monitoring/net-liveness.d.ts +143 -0
- package/dist/monitoring/net-liveness.js +301 -0
- package/dist/monitoring/net-liveness.js.map +1 -0
- package/dist/observability/progress.d.ts +11 -0
- package/dist/observability/progress.js +16 -0
- package/dist/observability/progress.js.map +1 -0
- package/dist/pilot/cost.d.ts +19 -0
- package/dist/pilot/cost.js +31 -0
- package/dist/pilot/cost.js.map +1 -0
- package/dist/pilot/instance.d.ts +20 -0
- package/dist/pilot/instance.js +19 -0
- package/dist/pilot/instance.js.map +1 -0
- package/dist/pilot/repo.d.ts +31 -0
- package/dist/pilot/repo.js +42 -0
- package/dist/pilot/repo.js.map +1 -0
- package/dist/pilot/solve.d.ts +22 -0
- package/dist/pilot/solve.js +37 -0
- package/dist/pilot/solve.js.map +1 -0
- package/dist/pilot/tally.d.ts +35 -0
- package/dist/pilot/tally.js +61 -0
- package/dist/pilot/tally.js.map +1 -0
- package/dist/plugins/local-trace-distiller/.claude-plugin/plugin.json +9 -0
- package/dist/plugins/local-trace-distiller/.codex-plugin/plugin.json +41 -0
- package/dist/plugins/local-trace-distiller/.mcp.json +8 -0
- package/dist/plugins/local-trace-distiller/README.md +27 -0
- package/dist/plugins/local-trace-distiller/jinn.plugin.json +36 -0
- package/dist/plugins/local-trace-distiller/skills/distill/SKILL.md +51 -0
- package/dist/preflight/rpc-network.d.ts +10 -3
- package/dist/preflight/rpc-network.js +46 -13
- package/dist/preflight/rpc-network.js.map +1 -1
- package/dist/preflight/stable-cwd.d.ts +29 -0
- package/dist/preflight/stable-cwd.js +98 -0
- package/dist/preflight/stable-cwd.js.map +1 -0
- package/dist/solvernets/launched-record-dispatcher.js +6 -0
- package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
- package/dist/spend/credential.d.ts +2 -2
- package/dist/spend/credential.js +9 -3
- package/dist/spend/credential.js.map +1 -1
- package/dist/spend/spend-cap.d.ts +10 -0
- package/dist/spend/spend-cap.js +13 -0
- package/dist/spend/spend-cap.js.map +1 -0
- package/dist/store/store.d.ts +14 -0
- package/dist/store/store.js +10 -1
- package/dist/store/store.js.map +1 -1
- package/dist/trajectory/processors/identity-scrub.js +22 -3
- package/dist/trajectory/processors/identity-scrub.js.map +1 -1
- package/dist/trajectory/scrub/build.d.ts +19 -0
- package/dist/trajectory/scrub/build.js +25 -0
- package/dist/trajectory/scrub/build.js.map +1 -1
- package/dist/trajectory/scrub/layer2.d.ts +23 -0
- package/dist/trajectory/scrub/layer2.js +33 -0
- package/dist/trajectory/scrub/layer2.js.map +1 -0
- package/dist/trajectory/scrub/openredaction-stage.d.ts +127 -0
- package/dist/trajectory/scrub/openredaction-stage.js +186 -2
- package/dist/trajectory/scrub/openredaction-stage.js.map +1 -1
- package/dist/trajectory/scrub/pipeline.d.ts +21 -0
- package/dist/trajectory/scrub/pipeline.js +57 -0
- package/dist/trajectory/scrub/pipeline.js.map +1 -1
- package/dist/trajectory/scrub/plain-patterns-stage.d.ts +14 -1
- package/dist/trajectory/scrub/plain-patterns-stage.js +35 -5
- package/dist/trajectory/scrub/plain-patterns-stage.js.map +1 -1
- package/dist/trajectory/scrub/secretlint-stage.d.ts +22 -3
- package/dist/trajectory/scrub/secretlint-stage.js +118 -27
- package/dist/trajectory/scrub/secretlint-stage.js.map +1 -1
- package/dist/trajectory/transcript-watcher.d.ts +26 -0
- package/dist/trajectory/transcript-watcher.js +33 -0
- package/dist/trajectory/transcript-watcher.js.map +1 -1
- package/dist/types/skill-artifact.d.ts +442 -0
- package/dist/types/skill-artifact.js +137 -0
- package/dist/types/skill-artifact.js.map +1 -0
- package/dist/types/task-run-read-model.d.ts +21 -0
- package/dist/types/task-run-read-model.js +2 -0
- package/dist/types/task-run-read-model.js.map +1 -0
- package/dist/types/task-run.d.ts +75 -0
- package/dist/types/task-run.js +2 -0
- package/dist/types/task-run.js.map +1 -0
- package/dist/util/redact-rpc-urls.d.ts +1 -1
- package/dist/util/redact-rpc-urls.js +57 -2
- package/dist/util/redact-rpc-urls.js.map +1 -1
- package/package.json +11 -8
- package/plugins/local-trace-distiller/.claude-plugin/plugin.json +9 -0
- package/plugins/local-trace-distiller/.codex-plugin/plugin.json +41 -0
- package/plugins/local-trace-distiller/.mcp.json +8 -0
- package/plugins/local-trace-distiller/README.md +27 -0
- package/plugins/local-trace-distiller/jinn.plugin.json +36 -0
- package/plugins/local-trace-distiller/skills/distill/SKILL.md +51 -0
- package/dist/api/peers.js.map +0 -1
- package/dist/dashboard/assets/index-BsrAAmvC.js +0 -171
- package/dist/dashboard/assets/index-DQOWJ2SF.css +0 -1
- /package/dist/{api/peers.d.ts → daemon/peer-sync.d.ts} +0 -0
package/dist/main.js
CHANGED
|
@@ -24,33 +24,35 @@ import { homedir, hostname, userInfo } from 'node:os';
|
|
|
24
24
|
import { randomBytes as cryptoRandomBytes } from 'node:crypto';
|
|
25
25
|
import { dirname, join } from 'node:path';
|
|
26
26
|
import { fileURLToPath } from 'node:url';
|
|
27
|
-
import { loadConfig, getConfigPathFromArgs, DEFAULT_CONFIG_PATH } from './config.js';
|
|
27
|
+
import { loadConfig, getConfigPathFromArgs, DEFAULT_CONFIG_PATH, DEFAULT_TESTNET_RPC_URLS } from './config.js';
|
|
28
28
|
import { Store } from './store/store.js';
|
|
29
29
|
import { startApiServer, isEmbeddedAgentEnabled } from './api/server.js';
|
|
30
|
-
import { setDefaultTxSubmissionLedger } from './tx-retry.js';
|
|
30
|
+
import { setDefaultTxSubmissionLedger, withEoaBroadcastLock } from './tx-retry.js';
|
|
31
31
|
// addHarnessReadinessRoutes is wired through startApiServer's holder ref now
|
|
32
32
|
// (jinn-mono-u34i). No direct import needed.
|
|
33
33
|
import { CapturePublishUnavailableError } from './api/captures.js';
|
|
34
34
|
import { invalidatePredictionOperatorStatusCache } from './api/gather-status.js';
|
|
35
35
|
import { ensureUiToken } from './api/ui-token.js';
|
|
36
36
|
import { getFileLogger, closeFileLogger } from './observability/file-logger.js';
|
|
37
|
+
import { emitProgress } from './observability/progress.js';
|
|
37
38
|
import { hashImplStateDir } from './harnesses/freeze.js';
|
|
38
39
|
import { readModeState } from './harnesses/mode-state.js';
|
|
39
40
|
import { attachAgentWs, updateAgentClaudePath } from './agent/agent-ws.js';
|
|
40
41
|
import { createSetupModeController } from './setup-mode.js';
|
|
41
42
|
import { requestDaemonRestart } from './restart-daemon.js';
|
|
42
|
-
import {
|
|
43
|
-
import { clearBootstrapError, persistBootstrapError, } from './errors/persisted-bootstrap-error.js';
|
|
43
|
+
import { emitEnvelope } from './errors/envelope.js';
|
|
44
44
|
import { emitStructured } from './events/emitter.js';
|
|
45
45
|
import { applyPidfileLivenessGate } from './preflight/pidfile-liveness.js';
|
|
46
46
|
import { applyDeploymentReadinessGate } from './preflight/deployment-readiness.js';
|
|
47
|
+
import { ensureStableCwd } from './preflight/stable-cwd.js';
|
|
47
48
|
import { detectAuthContext } from './preflight/claude-auth.js';
|
|
48
49
|
import { FleetBootstrapper, recoverEvictedService as recoverEvictedServiceFn } from './earning/bootstrap.js';
|
|
50
|
+
import { runFleetBootstrap, SetupBootstrapHalted } from './earning/bootstrap-run.js';
|
|
49
51
|
import { applyChainGasOverrides, getChainConfig } from './earning/contracts.js';
|
|
50
|
-
import {
|
|
52
|
+
import { getJinnRouterAddress } from './contracts/addresses.js';
|
|
51
53
|
import { FleetStateStore } from './earning/store.js';
|
|
52
|
-
import { isOperationalServiceStep
|
|
53
|
-
import { decryptMnemonic, deriveMasterSigner
|
|
54
|
+
import { isOperationalServiceStep } from './earning/types.js';
|
|
55
|
+
import { decryptMnemonic, deriveMasterSigner } from './earning/wallet.js';
|
|
54
56
|
import { MechAdapter } from './adapters/mech/adapter.js';
|
|
55
57
|
import { ClaudeRunner } from './runner/claude.js';
|
|
56
58
|
import { Daemon } from './daemon/daemon.js';
|
|
@@ -74,6 +76,7 @@ import { createCorpus } from './corpus/index.js';
|
|
|
74
76
|
import { DEFAULT_EXECUTION_DISCOVERY_FROM_BLOCK } from './corpus/onchain-query.js';
|
|
75
77
|
import { CapturesStore } from './store/captures.js';
|
|
76
78
|
import { createLiveCapturePublisher } from './captures/live-publisher.js';
|
|
79
|
+
import { EnsurePendingCaptureProcessor, ensurePendingCapture, ingestStopHookCapture } from './captures/ingest.js';
|
|
77
80
|
import { startReceiver } from './trajectory/receiver.js';
|
|
78
81
|
import { startSyntheticSpanProvider, emitSyntheticSpan } from './trajectory/synthetic-span-builder.js';
|
|
79
82
|
import { CredentialScrubProcessor } from './trajectory/processors/credential-scrub.js';
|
|
@@ -83,10 +86,6 @@ import { PathScrubProcessor } from './trajectory/processors/path-scrub.js';
|
|
|
83
86
|
import { buildScrubPipeline } from './trajectory/scrub/build.js';
|
|
84
87
|
import { maybeBuildPiiDetector } from './trajectory/scrub/pii-build.js';
|
|
85
88
|
import { SqliteExporterProcessor } from './trajectory/processors/sqlite-exporter.js';
|
|
86
|
-
import { ClaudeCodeJsonlParser } from './trajectory/transcript-parsers/claude-code-jsonl.js';
|
|
87
|
-
import { CodexSessionParser } from './trajectory/transcript-parsers/codex-session.js';
|
|
88
|
-
import { GeminiSessionParser } from './trajectory/transcript-parsers/gemini-session.js';
|
|
89
|
-
import { CursorSqliteParser } from './trajectory/transcript-parsers/cursor-sqlite.js';
|
|
90
89
|
import { startTranscriptWatcher, } from './trajectory/transcript-watcher.js';
|
|
91
90
|
import { defaultTranscriptWatchDirectories } from './trajectory/transcript-session-dirs.js';
|
|
92
91
|
import { buildInfo } from './build-info.js';
|
|
@@ -95,7 +94,6 @@ import { GeneratedTaskSource, StaticConfiguredTaskSource, filterBindableTasks }
|
|
|
95
94
|
import { checkRpcNetwork, logRpcLocalDevToStderr, probeFallbackChain, rpcNetworkFailureHint, summarizeFallbackChain, } from './preflight/rpc-network.js';
|
|
96
95
|
import { apiPortFailureMessage, checkApiPortAvailable } from './preflight/api-port.js';
|
|
97
96
|
import { openBrowser } from './cli/open-browser.js';
|
|
98
|
-
import { keepSetupUiOnBootstrapError } from './setup/halt-mode.js';
|
|
99
97
|
if (process.env['JINN_LOAD_DEV_ENV'] === '1' || process.env['NODE_ENV'] === 'development') {
|
|
100
98
|
dotenvConfig({ path: join(dirname(fileURLToPath(import.meta.url)), '..', '.env') });
|
|
101
99
|
}
|
|
@@ -183,456 +181,40 @@ const CHAIN_CONFIG = applyChainGasOverrides(getChainConfig(NETWORK_CHAIN, {
|
|
|
183
181
|
minSafeEthWei: config.minSafeEthWei,
|
|
184
182
|
});
|
|
185
183
|
const MARKETPLACE_ADDRESS = CHAIN_CONFIG.mechMarketplace;
|
|
186
|
-
const ROUTER_ADDRESS = (CHAIN_CONFIG.jinnRouter ??
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
capturedAt: hrTimeToIso(span.startTime),
|
|
202
|
-
tool: inferCaptureTool(span),
|
|
203
|
-
capturePath: inferCapturePath(span),
|
|
204
|
-
...repoMetadataFromSpan(span),
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
function stringAttribute(value) {
|
|
209
|
-
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
|
210
|
-
}
|
|
211
|
-
function hrTimeToIso(time) {
|
|
212
|
-
const millis = (time[0] * 1000) + Math.floor(time[1] / 1_000_000);
|
|
213
|
-
return new Date(millis).toISOString();
|
|
214
|
-
}
|
|
215
|
-
function inferCaptureTool(span) {
|
|
216
|
-
return stringAttribute(span.attributes['transcript.tool'])
|
|
217
|
-
?? stringAttribute(span.resource.attributes['service.name'])
|
|
218
|
-
?? 'otel';
|
|
219
|
-
}
|
|
220
|
-
function inferCapturePath(span) {
|
|
221
|
-
if (stringAttribute(span.attributes['transcript.tool']))
|
|
222
|
-
return 'B';
|
|
223
|
-
return 'A';
|
|
224
|
-
}
|
|
225
|
-
function repoMetadataFromSpan(span) {
|
|
226
|
-
const attrs = span.attributes;
|
|
227
|
-
const repoRemoteUrl = stringAttribute(attrs['repo.remote_url'])
|
|
228
|
-
?? stringAttribute(attrs['vcs.repository.url'])
|
|
229
|
-
?? stringAttribute(attrs['git.remote_url']);
|
|
230
|
-
const repoCommitHash = stringAttribute(attrs['repo.commit_hash'])
|
|
231
|
-
?? stringAttribute(attrs['vcs.ref.head.revision'])
|
|
232
|
-
?? stringAttribute(attrs['git.commit']);
|
|
233
|
-
return {
|
|
234
|
-
...(repoRemoteUrl ? { repoRemoteUrl } : {}),
|
|
235
|
-
...(repoCommitHash ? { repoCommitHash } : {}),
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
function parserForStopHookTool(tool) {
|
|
239
|
-
switch (tool) {
|
|
240
|
-
case 'claude-code':
|
|
241
|
-
return new ClaudeCodeJsonlParser();
|
|
242
|
-
case 'codex':
|
|
243
|
-
return new CodexSessionParser();
|
|
244
|
-
case 'gemini-cli':
|
|
245
|
-
return new GeminiSessionParser();
|
|
246
|
-
case 'cursor':
|
|
247
|
-
return new CursorSqliteParser();
|
|
248
|
-
default: {
|
|
249
|
-
const exhaustive = tool;
|
|
250
|
-
throw new Error(`No transcript parser for stop-hook tool: ${String(exhaustive)}`);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
function ensurePendingCapture(captures, params) {
|
|
255
|
-
if (captures.getBySession(params.sessionId))
|
|
256
|
-
return;
|
|
257
|
-
try {
|
|
258
|
-
captures.savePending({
|
|
259
|
-
sessionId: params.sessionId,
|
|
260
|
-
capturedAt: params.capturedAt,
|
|
261
|
-
originatingTool: { name: params.tool },
|
|
262
|
-
capturePath: params.capturePath,
|
|
263
|
-
status: 'pending',
|
|
264
|
-
spanCount: 0,
|
|
265
|
-
durationMs: 0,
|
|
266
|
-
redactedSpanCount: 0,
|
|
267
|
-
...(params.repoRemoteUrl ? { repoRemoteUrl: params.repoRemoteUrl } : {}),
|
|
268
|
-
...(params.repoCommitHash ? { repoCommitHash: params.repoCommitHash } : {}),
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
catch (err) {
|
|
272
|
-
if (!captures.getBySession(params.sessionId))
|
|
273
|
-
throw err;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
async function ingestStopHookCapture(captures, receiver, payload) {
|
|
277
|
-
ensurePendingCapture(captures, {
|
|
278
|
-
sessionId: payload.sessionId,
|
|
279
|
-
capturedAt: payload.stoppedAt,
|
|
280
|
-
tool: payload.tool,
|
|
281
|
-
capturePath: 'D',
|
|
282
|
-
});
|
|
283
|
-
if (!payload.transcriptPath)
|
|
284
|
-
return;
|
|
285
|
-
if (!receiver) {
|
|
286
|
-
console.warn('[main] stop-hook capture received but OTLP receiver is unavailable; pending capture has no transcript spans.');
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const parser = parserForStopHookTool(payload.tool);
|
|
290
|
-
let events;
|
|
291
|
-
try {
|
|
292
|
-
events = await parser.parseFull({ sessionId: payload.sessionId, path: payload.transcriptPath });
|
|
293
|
-
}
|
|
294
|
-
catch (err) {
|
|
295
|
-
console.warn(`[main] stop-hook transcript import failed for ${payload.transcriptPath}: ` +
|
|
296
|
-
`${err instanceof Error ? err.message : String(err)}`);
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
if (events.length === 0)
|
|
300
|
-
return;
|
|
301
|
-
const provider = startSyntheticSpanProvider({
|
|
302
|
-
otlpHttpEndpoint: `http://127.0.0.1:${receiver.httpPort}/v1/traces`,
|
|
303
|
-
});
|
|
184
|
+
const ROUTER_ADDRESS = (CHAIN_CONFIG.jinnRouter ?? getJinnRouterAddress(CHAIN_CONFIG.chainId));
|
|
185
|
+
/** #913: the bundled public RPC fallback chain for the current network. The
|
|
186
|
+
* setup/network endpoint persists `[primary, ...RPC_PUBLIC_DEFAULTS]` so the
|
|
187
|
+
* operator keeps the public backup chain when they set a primary, and the
|
|
188
|
+
* Settings → Network UI renders these as the trailing read-only slots. */
|
|
189
|
+
const RPC_PUBLIC_DEFAULTS = NETWORK_CHAIN === 'base-sepolia' ? DEFAULT_TESTNET_RPC_URLS : [CHAIN_CONFIG.rpcUrl];
|
|
190
|
+
/** #913: last L2 boot-probe result per RPC slot. Captured at boot, surfaced
|
|
191
|
+
* via /v1/bootstrap so Settings → Network can render per-slot health. Hosts
|
|
192
|
+
* are already masked by probeFallbackChain. The RPC chain is restart-required,
|
|
193
|
+
* so this never drifts without a re-probing restart. */
|
|
194
|
+
let lastL2Probe = [];
|
|
195
|
+
function configFileHasTopLevelKey(configPath, key) {
|
|
196
|
+
const filePath = configPath ?? join(process.env['HOME'] ?? '', '.jinn-client', 'config.json');
|
|
197
|
+
if (!filePath || !existsSync(filePath))
|
|
198
|
+
return false;
|
|
304
199
|
try {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
await provider.flush();
|
|
200
|
+
const raw = JSON.parse(readFileSync(filePath, 'utf8'));
|
|
201
|
+
return !!raw && typeof raw === 'object' && Object.prototype.hasOwnProperty.call(raw, key);
|
|
309
202
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
const STANDARD_SERVICE_PROGRESSION = [
|
|
315
|
-
'awaiting_stake',
|
|
316
|
-
'staked',
|
|
317
|
-
'mech_deployed',
|
|
318
|
-
'agent_registered',
|
|
319
|
-
'safe_binding_pending',
|
|
320
|
-
'complete',
|
|
321
|
-
];
|
|
322
|
-
const SELF_BOND_SERVICE_PROGRESSION = [
|
|
323
|
-
'awaiting_stake',
|
|
324
|
-
'service_created',
|
|
325
|
-
'service_activated',
|
|
326
|
-
'agents_registered',
|
|
327
|
-
'service_deployed',
|
|
328
|
-
'service_staked',
|
|
329
|
-
'mech_deployed',
|
|
330
|
-
'agent_registered',
|
|
331
|
-
'safe_binding_pending',
|
|
332
|
-
'complete',
|
|
333
|
-
];
|
|
334
|
-
/** §6.2 `bootstrap_incomplete` — `{ currentStep, nextStep }` from persisted fleet state. */
|
|
335
|
-
function bootstrapIncompleteSteps(state) {
|
|
336
|
-
const progression = state.staking_mode === 'self-bond'
|
|
337
|
-
? SELF_BOND_SERVICE_PROGRESSION
|
|
338
|
-
: STANDARD_SERVICE_PROGRESSION;
|
|
339
|
-
const byIndex = [...state.services].sort((a, b) => a.index - b.index);
|
|
340
|
-
const focus = byIndex.find(s => isOperationalServiceStep(s.step) && !s.safe_address) ??
|
|
341
|
-
byIndex.find(s => !isOperationalServiceStep(s.step)) ??
|
|
342
|
-
byIndex.find(s => s.step === 'safe_binding_pending') ??
|
|
343
|
-
byIndex[0];
|
|
344
|
-
if (!focus) {
|
|
345
|
-
return { currentStep: 'awaiting_service', nextStep: 'awaiting_stake' };
|
|
346
|
-
}
|
|
347
|
-
if (isOperationalServiceStep(focus.step) && !focus.safe_address) {
|
|
348
|
-
return { currentStep: 'complete', nextStep: 'bootstrap' };
|
|
349
|
-
}
|
|
350
|
-
const i = progression.indexOf(focus.step);
|
|
351
|
-
if (i === -1) {
|
|
352
|
-
return { currentStep: focus.step, nextStep: 'bootstrap' };
|
|
353
|
-
}
|
|
354
|
-
if (i < progression.length - 1) {
|
|
355
|
-
return { currentStep: focus.step, nextStep: progression[i + 1] };
|
|
356
|
-
}
|
|
357
|
-
return { currentStep: focus.step, nextStep: 'bootstrap' };
|
|
358
|
-
}
|
|
359
|
-
// ── Bootstrap ───────────────────────────────────────────────────────────────
|
|
360
|
-
async function bootstrap() {
|
|
361
|
-
console.log('[main] Running fleet bootstrap...');
|
|
362
|
-
// A fresh bootstrap attempt clears any stale error breadcrumb. If this run
|
|
363
|
-
// hits the same failure, it'll be re-persisted below; if it succeeds (or
|
|
364
|
-
// proceeds past the previously-failed step), the panel returns to a clean
|
|
365
|
-
// state on the next /v1/bootstrap poll.
|
|
366
|
-
clearBootstrapError(config.earningDir);
|
|
367
|
-
// Persist the envelope to disk before emitEnvelope's process.exit fires,
|
|
368
|
-
// so /v1/bootstrap can surface it to the panel after the daemon has
|
|
369
|
-
// exited (operator restart → panel reload → error visible).
|
|
370
|
-
function failBootstrap(input) {
|
|
371
|
-
const envelope = buildEnvelope(input);
|
|
372
|
-
persistBootstrapError(envelope, config.earningDir);
|
|
373
|
-
if (keepSetupUiOnBootstrapError()) {
|
|
374
|
-
emitStructured({
|
|
375
|
-
kind: 'error',
|
|
376
|
-
message: envelope.message,
|
|
377
|
-
errorCode: envelope.code,
|
|
378
|
-
details: {
|
|
379
|
-
phase: 'bootstrap',
|
|
380
|
-
exitCode: envelope.exitCode,
|
|
381
|
-
...(envelope.details ?? {}),
|
|
382
|
-
},
|
|
383
|
-
});
|
|
384
|
-
console.error(`[main] Bootstrap halted (${envelope.code}); setup UI remains available. ` +
|
|
385
|
-
`Resolve the issue and run jinn run again.`);
|
|
386
|
-
throw new SetupBootstrapHalted(envelope);
|
|
387
|
-
}
|
|
388
|
-
emitEnvelope(input);
|
|
389
|
-
// Unreachable in production (emitEnvelope exits); satisfies `never`.
|
|
390
|
-
throw new Error('unreachable');
|
|
391
|
-
}
|
|
392
|
-
const bootstrapper = new FleetBootstrapper({
|
|
393
|
-
earningDir: config.earningDir,
|
|
394
|
-
chain: NETWORK_CHAIN,
|
|
395
|
-
rpcUrl: config.rpcUrl,
|
|
396
|
-
stakingMode: config.stakingMode,
|
|
397
|
-
targetServices: config.targetServices,
|
|
398
|
-
testnetL2DeploymentPath: config.testnetL2DeploymentPath,
|
|
399
|
-
testnetL2TokenDeploymentPath: config.testnetL2TokenDeploymentPath,
|
|
400
|
-
testnetMechDeploymentPath: config.testnetMechDeploymentPath,
|
|
401
|
-
testnetStolasDeploymentPath: config.testnetStolasDeploymentPath,
|
|
402
|
-
debug: config.debug,
|
|
403
|
-
masterEthDailyEstimateWei: config.masterEthDailyEstimateWei,
|
|
404
|
-
minEoaGasWei: config.minEoaGasWei,
|
|
405
|
-
minSafeEthWei: config.minSafeEthWei,
|
|
406
|
-
pollIntervalMs: config.pollIntervalMs,
|
|
407
|
-
autoTestnetFaucet: process.env['JINN_AUTO_TESTNET_FAUCET'] === '1',
|
|
408
|
-
});
|
|
409
|
-
// Funding poll: stay up while waiting for the operator to fund the wallet.
|
|
410
|
-
// The setup-mode API server is already running; the panel renders the
|
|
411
|
-
// funding card and auto-advances when funds land. Daemon-side, we poll
|
|
412
|
-
// bootstrap on a 15s tick and only escalate (exit) if a non-funding error
|
|
413
|
-
// occurs or the configured timeout elapses. Each tick re-runs the full
|
|
414
|
-
// bootstrap state machine — completed steps are no-ops, so this is safe.
|
|
415
|
-
// Testnet faucet funding is panel-driven: bootstrap reports the funding gate,
|
|
416
|
-
// and the operator clicks the funding action before this loop can advance.
|
|
417
|
-
const FUNDING_POLL_INTERVAL_MS = 15_000;
|
|
418
|
-
const fundingTimeoutMs = (() => {
|
|
419
|
-
const raw = process.env['JINN_FUNDING_TIMEOUT_MS'];
|
|
420
|
-
if (!raw)
|
|
421
|
-
return Number.POSITIVE_INFINITY;
|
|
422
|
-
const n = Number.parseInt(raw, 10);
|
|
423
|
-
return Number.isFinite(n) && n > 0 ? n : Number.POSITIVE_INFINITY;
|
|
424
|
-
})();
|
|
425
|
-
emitProgress({
|
|
426
|
-
type: 'progress',
|
|
427
|
-
phase: 'bootstrap',
|
|
428
|
-
step: 'advance_state_machine',
|
|
429
|
-
estimatedWaitMs: 60_000,
|
|
430
|
-
});
|
|
431
|
-
const fundingStartedAt = Date.now();
|
|
432
|
-
let result;
|
|
433
|
-
let lastFundingMessage = '';
|
|
434
|
-
const fundingGatePath = join(config.earningDir, 'bootstrap-funding.json');
|
|
435
|
-
const persistFundingGate = (funding) => {
|
|
436
|
-
mkdirSync(config.earningDir, { recursive: true, mode: 0o700 });
|
|
437
|
-
writeFileSyncMain(fundingGatePath, `${JSON.stringify({
|
|
438
|
-
schemaVersion: 1,
|
|
439
|
-
generatedAt: new Date().toISOString(),
|
|
440
|
-
...funding,
|
|
441
|
-
}, null, 2)}\n`, { mode: 0o600 });
|
|
442
|
-
};
|
|
443
|
-
const clearFundingGate = () => {
|
|
444
|
-
try {
|
|
445
|
-
unlinkSync(fundingGatePath);
|
|
446
|
-
}
|
|
447
|
-
catch {
|
|
448
|
-
// best-effort: absent/stale funding gate should not affect bootstrap
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
// eslint-disable-next-line no-constant-condition
|
|
452
|
-
while (true) {
|
|
453
|
-
result = await bootstrapper.ensureStage1And2(PASSWORD);
|
|
454
|
-
if (!result.funding) {
|
|
455
|
-
clearFundingGate();
|
|
456
|
-
break;
|
|
457
|
-
}
|
|
458
|
-
persistFundingGate(result.funding);
|
|
459
|
-
// Emit a structured event so the panel's Visibility region shows the gate.
|
|
460
|
-
// Dedupe by message to avoid spamming the ring buffer on each poll.
|
|
461
|
-
const fundingMsg = result.message ?? 'awaiting funding';
|
|
462
|
-
if (fundingMsg !== lastFundingMessage) {
|
|
463
|
-
emitStructured({
|
|
464
|
-
kind: 'fleet',
|
|
465
|
-
message: fundingMsg,
|
|
466
|
-
details: {
|
|
467
|
-
phase: 'awaiting_funding',
|
|
468
|
-
role: 'master',
|
|
469
|
-
address: result.funding.master_address,
|
|
470
|
-
asset: 'native',
|
|
471
|
-
needWei: result.funding.eth_required,
|
|
472
|
-
haveWei: result.funding.eth_balance,
|
|
473
|
-
},
|
|
474
|
-
});
|
|
475
|
-
// Mirror the structured event to NDJSON progress for --json-progress
|
|
476
|
-
// consumers (CI, agents). Same dedup gate so we don't spam stdout.
|
|
477
|
-
emitProgress({
|
|
478
|
-
type: 'progress',
|
|
479
|
-
phase: 'bootstrap',
|
|
480
|
-
step: 'awaiting_funding',
|
|
481
|
-
blocking: true,
|
|
482
|
-
nextAction: 'Fund the address shown in addresses.fundingAddress, then wait for automatic retry.',
|
|
483
|
-
addresses: { fundingAddress: result.funding.master_address },
|
|
484
|
-
estimatedWaitMs: 1_800_000,
|
|
485
|
-
});
|
|
486
|
-
lastFundingMessage = fundingMsg;
|
|
487
|
-
}
|
|
488
|
-
const elapsed = Date.now() - fundingStartedAt;
|
|
489
|
-
if (elapsed >= fundingTimeoutMs) {
|
|
490
|
-
failBootstrap({
|
|
491
|
-
code: 'funding_required',
|
|
492
|
-
message: `${result.message} (timeout after ${Math.round(elapsed / 1000)}s)`,
|
|
493
|
-
hint: 'Fund the listed address and re-run this command.',
|
|
494
|
-
exampleCli: 'jinn fund-requirements --json',
|
|
495
|
-
details: {
|
|
496
|
-
// jinn-mono-hjex.6: structured envelope so SPA can render the
|
|
497
|
-
// specific address + amount instead of a prose disjunction.
|
|
498
|
-
category: 'insufficient_funds',
|
|
499
|
-
step: 'awaiting_funding',
|
|
500
|
-
address: result.funding.master_address,
|
|
501
|
-
requiredWei: result.funding.eth_required,
|
|
502
|
-
haveWei: result.funding.eth_balance,
|
|
503
|
-
// Legacy aliases kept for any external consumers that read these.
|
|
504
|
-
role: 'master',
|
|
505
|
-
asset: 'native',
|
|
506
|
-
needWei: result.funding.eth_required,
|
|
507
|
-
},
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
console.log(`[main] Awaiting funding... (${Math.round(elapsed / 1000)}s elapsed; ` +
|
|
511
|
-
`will retry in ${FUNDING_POLL_INTERVAL_MS / 1000}s)`);
|
|
512
|
-
await new Promise((r) => setTimeout(r, FUNDING_POLL_INTERVAL_MS));
|
|
513
|
-
}
|
|
514
|
-
if (!result.ok) {
|
|
515
|
-
failBootstrap({
|
|
516
|
-
code: 'fatal',
|
|
517
|
-
message: result.message,
|
|
518
|
-
hint: 'Bootstrap failed before the fleet reached a runnable state.',
|
|
519
|
-
details: {
|
|
520
|
-
cause: result.message,
|
|
521
|
-
// jinn-mono-hjex.6: propagate structured category from the bootstrapper
|
|
522
|
-
// so the SPA can render category-specific UI (e.g. funding shortfall).
|
|
523
|
-
...(result.errorCategory !== undefined ? { category: result.errorCategory } : {}),
|
|
524
|
-
// Preserve the raw underlying error so a misclassified summary can
|
|
525
|
-
// be diagnosed without re-running with JINN_DEBUG. See jinn-mono-jz9f.
|
|
526
|
-
...(result.rawErrorMessage && result.rawErrorMessage !== result.message
|
|
527
|
-
? { rawErrorMessage: result.rawErrorMessage }
|
|
528
|
-
: {}),
|
|
529
|
-
// jinn-mono-hjex reviewer fix: propagate tx hash so the SPA can render
|
|
530
|
-
// a block-explorer link for failed on-chain revert transactions.
|
|
531
|
-
...(result.txHash != null ? { txHash: result.txHash } : {}),
|
|
532
|
-
},
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
// Legacy migration (jinn-mono-jgp): backfill `agent_id` on `complete`
|
|
536
|
-
// services that pre-date j07. Idempotent + per-service failure-isolated;
|
|
537
|
-
// a failure here does not abort daemon startup, but we surface counts so
|
|
538
|
-
// operators notice. Disabled via `runLegacyMigrations: false` /
|
|
539
|
-
// JINN_RUN_LEGACY_MIGRATIONS=0 — operators can run `jinn migrate-agent-id`
|
|
540
|
-
// explicitly instead.
|
|
541
|
-
let state = result.fleet_state;
|
|
542
|
-
if (config.runLegacyMigrations) {
|
|
543
|
-
try {
|
|
544
|
-
const migration = await runLegacyAgentIdMigration({
|
|
545
|
-
earningDir: config.earningDir,
|
|
546
|
-
network: NETWORK_CHAIN,
|
|
547
|
-
rpcUrl: config.rpcUrl,
|
|
548
|
-
password: PASSWORD,
|
|
549
|
-
testnetL2DeploymentPath: config.testnetL2DeploymentPath,
|
|
550
|
-
testnetL2TokenDeploymentPath: config.testnetL2TokenDeploymentPath,
|
|
551
|
-
testnetMechDeploymentPath: config.testnetMechDeploymentPath,
|
|
552
|
-
testnetStolasDeploymentPath: config.testnetStolasDeploymentPath,
|
|
553
|
-
});
|
|
554
|
-
if (migration.migrated.length > 0 || migration.failed.length > 0) {
|
|
555
|
-
console.log(`[main] Legacy agent_id migration: migrated=${migration.migrated.length} ` +
|
|
556
|
-
`skipped=${migration.skipped.length} failed=${migration.failed.length}`);
|
|
557
|
-
for (const f of migration.failed) {
|
|
558
|
-
console.log(`[main] service ${f.service.index} (agent ${f.service.agent_address}): ${f.error}`);
|
|
559
|
-
}
|
|
560
|
-
// Reload state so downstream wiring (agent_id, identityRegistry)
|
|
561
|
-
// sees the migrated rows.
|
|
562
|
-
state = await new FleetStateStore(config.earningDir).load(NETWORK_CHAIN);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
catch (err) {
|
|
566
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
567
|
-
console.error(`[main] Legacy agent_id migration failed (non-fatal): ${message}`);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
// Use the first operational service for the daemon. `safe_binding_pending`
|
|
571
|
-
// means staking/mech are live; only the ERC-8004 Safe→agent metadata bind
|
|
572
|
-
// is still retrying.
|
|
573
|
-
const firstComplete = state.services.find(s => isOperationalServiceStep(s.step));
|
|
574
|
-
if (!firstComplete || !firstComplete.safe_address) {
|
|
575
|
-
failBootstrap({
|
|
576
|
-
code: 'bootstrap_incomplete',
|
|
577
|
-
message: 'Bootstrap completed but no service is ready.',
|
|
578
|
-
hint: 'Re-run to continue the state machine toward a running fleet.',
|
|
579
|
-
exampleCli: 'jinn bootstrap --json',
|
|
580
|
-
details: bootstrapIncompleteSteps(state),
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
// Derive agent private key from mnemonic
|
|
584
|
-
const store = new FleetStateStore(config.earningDir);
|
|
585
|
-
const mnemonic = await decryptMnemonic(await store.loadMnemonicKeystore(), PASSWORD);
|
|
586
|
-
const agentPrivateKey = walletPrivateKeyAtIndex(mnemonic, firstComplete.index);
|
|
587
|
-
console.log(`[main] Fleet bootstrap complete.`);
|
|
588
|
-
console.log(` Master: ${state.master_address}`);
|
|
589
|
-
console.log(` Services: ${state.services.filter(s => isOperationalServiceStep(s.step)).length}/${config.targetServices}`);
|
|
590
|
-
console.log(` Active: service ${firstComplete.service_id} (agent ${firstComplete.agent_address})`);
|
|
591
|
-
if (firstComplete.mech_address) {
|
|
592
|
-
console.log(` Mech: ${firstComplete.mech_address}`);
|
|
593
|
-
}
|
|
594
|
-
return {
|
|
595
|
-
masterAddress: state.master_address,
|
|
596
|
-
serviceIndex: firstComplete.index,
|
|
597
|
-
serviceId: firstComplete.service_id ?? null,
|
|
598
|
-
stakingAddress: firstComplete.staking_address ? firstComplete.staking_address : null,
|
|
599
|
-
agentPrivateKey: agentPrivateKey,
|
|
600
|
-
safeAddress: firstComplete.safe_address,
|
|
601
|
-
mechAddress: firstComplete.mech_address ? firstComplete.mech_address : undefined,
|
|
602
|
-
agentId: firstComplete.agent_id ?? null,
|
|
603
|
-
identityRegistryAddress: firstComplete.identity_registry_address
|
|
604
|
-
? firstComplete.identity_registry_address
|
|
605
|
-
: null,
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
class SetupBootstrapHalted extends Error {
|
|
609
|
-
envelope;
|
|
610
|
-
constructor(envelope) {
|
|
611
|
-
super(envelope.message);
|
|
612
|
-
this.envelope = envelope;
|
|
613
|
-
this.name = 'SetupBootstrapHalted';
|
|
203
|
+
catch {
|
|
204
|
+
return false;
|
|
614
205
|
}
|
|
615
206
|
}
|
|
616
207
|
// hjex.6: gate for the halt-and-resume loop. Lives in ./setup/halt-mode.ts
|
|
617
208
|
// so it can be unit-tested without dragging main.ts's top-level side
|
|
618
209
|
// effects (password resolution, config load) into the test.
|
|
619
210
|
// ── Main ────────────────────────────────────────────────────────────────────
|
|
620
|
-
/**
|
|
621
|
-
* --json-progress: emit NDJSON progress envelopes on stdout during long
|
|
622
|
-
* phases (init, bootstrap, daemon startup). The `jinn run --json-progress`
|
|
623
|
-
* flag flips JINN_JSON_PROGRESS=1 in run.ts before calling main(); when
|
|
624
|
-
* unset this is a no-op so tests / non-flag invocations stay silent on
|
|
625
|
-
* stdout.
|
|
626
|
-
*/
|
|
627
|
-
function progressEnabled() {
|
|
628
|
-
return process.env['JINN_JSON_PROGRESS'] === '1';
|
|
629
|
-
}
|
|
630
|
-
function emitProgress(envelope) {
|
|
631
|
-
if (progressEnabled()) {
|
|
632
|
-
process.stdout.write(JSON.stringify(envelope) + '\n');
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
211
|
export async function main() {
|
|
212
|
+
// Issue #909: chdir to a stable directory before spawning any child process.
|
|
213
|
+
// `jinn run` inherits the launch shell's CWD; when daemonised from an
|
|
214
|
+
// ephemeral dir that is later deleted, the CWD becomes a dangling inode and
|
|
215
|
+
// child processes (the `claude` CLI harness probe) crash on getcwd() ENOENT.
|
|
216
|
+
// Must run first — before getFileLogger() and any subprocess spawn.
|
|
217
|
+
ensureStableCwd({ earningDir: config.earningDir });
|
|
636
218
|
console.log(`[main] jinn-client starting on ${NETWORK_CHAIN}`);
|
|
637
219
|
// Issue #420: initialise the rotating daemon file logger early so lifecycle
|
|
638
220
|
// events (tapped in `observability/emit-event.ts`) accumulate durable,
|
|
@@ -682,7 +264,7 @@ export async function main() {
|
|
|
682
264
|
// Boot-time RPC fallback-chain probe (issue #592, AC7 + AC9). Log-only —
|
|
683
265
|
// per-slot 429s/5xx never gate startup. checkRpcNetwork above already
|
|
684
266
|
// fail-loud on chain-id mismatch against the head provider.
|
|
685
|
-
await probeFallbackChain(config.rpcUrls, config.network, 'L2');
|
|
267
|
+
lastL2Probe = await probeFallbackChain(config.rpcUrls, config.network, 'L2');
|
|
686
268
|
console.error(summarizeFallbackChain('L2', config.rpcUrls));
|
|
687
269
|
const portPreflight = await checkApiPortAvailable(config.apiPort);
|
|
688
270
|
if (!portPreflight.ok) {
|
|
@@ -950,6 +532,25 @@ export async function main() {
|
|
|
950
532
|
configReader: () => ({
|
|
951
533
|
rpcUrl: config.rpcUrl,
|
|
952
534
|
defaultRpcUrl: CHAIN_CONFIG.rpcUrl,
|
|
535
|
+
rpcUrls: config.rpcUrls,
|
|
536
|
+
publicDefaults: RPC_PUBLIC_DEFAULTS,
|
|
537
|
+
rpcSlotHealth: lastL2Probe.map((p) => p.ok
|
|
538
|
+
? {
|
|
539
|
+
ok: true,
|
|
540
|
+
host: p.host,
|
|
541
|
+
latencyMs: p.latencyMs,
|
|
542
|
+
expectedChainId: p.expectedChainId,
|
|
543
|
+
actualChainId: p.actualChainId,
|
|
544
|
+
...(p.localDev ? { localDev: true } : {}),
|
|
545
|
+
}
|
|
546
|
+
: {
|
|
547
|
+
ok: false,
|
|
548
|
+
host: p.host,
|
|
549
|
+
code: p.code,
|
|
550
|
+
reason: p.reason,
|
|
551
|
+
expectedChainId: p.expectedChainId,
|
|
552
|
+
actualChainId: p.actualChainId,
|
|
553
|
+
}),
|
|
953
554
|
joinedSolverNets: config.joinedSolverNets,
|
|
954
555
|
onboardingComplete: config.onboardingComplete,
|
|
955
556
|
}),
|
|
@@ -1076,6 +677,7 @@ export async function main() {
|
|
|
1076
677
|
getClaudePath: () => activeClaudePath,
|
|
1077
678
|
configPath: CONFIG_PATH ?? DEFAULT_CONFIG_PATH,
|
|
1078
679
|
defaultRpcUrlForChain: () => CHAIN_CONFIG.rpcUrl,
|
|
680
|
+
defaultRpcUrlsForChain: () => RPC_PUBLIC_DEFAULTS,
|
|
1079
681
|
onClaudePathSelected: selectClaudePath,
|
|
1080
682
|
// Issue #421 retired the legacy `solverNets` write target. Setup
|
|
1081
683
|
// endpoints no longer call back into the daemon to mutate operator
|
|
@@ -1225,6 +827,11 @@ export async function main() {
|
|
|
1225
827
|
const rows = sharedStore.listPostedTasksByCreator(opts);
|
|
1226
828
|
return rows.map((r) => ({
|
|
1227
829
|
taskId: r.taskId,
|
|
830
|
+
// On-chain decimal id (#579) — the launcher status chip keys its
|
|
831
|
+
// indexer lookup on this, not the off-chain display taskId. Empty
|
|
832
|
+
// string (no on-chain id recorded) maps to undefined so the
|
|
833
|
+
// gatherer falls back to taskId.
|
|
834
|
+
...(r.protocolTaskId ? { protocolTaskId: r.protocolTaskId } : {}),
|
|
1228
835
|
taskCid: r.taskCid,
|
|
1229
836
|
solverType: r.solverType ?? undefined,
|
|
1230
837
|
postedAt: r.postedAt,
|
|
@@ -1232,6 +839,16 @@ export async function main() {
|
|
|
1232
839
|
...(r.claims ? { claims: r.claims } : {}),
|
|
1233
840
|
}));
|
|
1234
841
|
},
|
|
842
|
+
// #579: on-chain finalized/open/expired status for the Recent posted
|
|
843
|
+
// Tasks chip. discoveryApiHolder is populated post-bootstrap; before
|
|
844
|
+
// that (or with no discovery API) we return an empty Map → all chips
|
|
845
|
+
// render 'unknown', the safe degraded default.
|
|
846
|
+
fetchTaskStatuses: async (manifestCid) => {
|
|
847
|
+
const api = discoveryApiHolder.current;
|
|
848
|
+
if (!api)
|
|
849
|
+
return new Map();
|
|
850
|
+
return api.getTaskStatuses({ manifestCid });
|
|
851
|
+
},
|
|
1235
852
|
},
|
|
1236
853
|
},
|
|
1237
854
|
});
|
|
@@ -1355,7 +972,7 @@ export async function main() {
|
|
|
1355
972
|
// eslint-disable-next-line no-constant-condition
|
|
1356
973
|
while (true) {
|
|
1357
974
|
try {
|
|
1358
|
-
bootstrapResult = await
|
|
975
|
+
bootstrapResult = await runFleetBootstrap({ config, password: PASSWORD, network: NETWORK_CHAIN, emitProgress });
|
|
1359
976
|
break; // success — exit the retry loop
|
|
1360
977
|
}
|
|
1361
978
|
catch (err) {
|
|
@@ -2261,7 +1878,7 @@ export async function main() {
|
|
|
2261
1878
|
store: earningStore,
|
|
2262
1879
|
chain: NETWORK_CHAIN,
|
|
2263
1880
|
writeCheckpoint: async ({ stakingProxy }) => {
|
|
2264
|
-
const txHash = await masterWallet.writeContract({
|
|
1881
|
+
const txHash = await withEoaBroadcastLock(masterAccount.address, () => masterWallet.writeContract({
|
|
2265
1882
|
address: stakingProxy,
|
|
2266
1883
|
abi: [
|
|
2267
1884
|
{
|
|
@@ -2275,7 +1892,7 @@ export async function main() {
|
|
|
2275
1892
|
functionName: 'checkpoint',
|
|
2276
1893
|
account: masterAccount,
|
|
2277
1894
|
chain: null,
|
|
2278
|
-
});
|
|
1895
|
+
}));
|
|
2279
1896
|
return { txHash };
|
|
2280
1897
|
},
|
|
2281
1898
|
}
|