@jinn-network/client 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -1
- package/dist/adapters/mech/adapter.d.ts +19 -1
- package/dist/adapters/mech/adapter.js +130 -14
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +22 -1
- package/dist/adapters/mech/contracts.js +34 -24
- package/dist/adapters/mech/contracts.js.map +1 -1
- package/dist/adapters/mech/safe.d.ts +1 -1
- package/dist/adapters/mech/safe.js +5 -3
- package/dist/adapters/mech/safe.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +6 -1
- package/dist/adapters/mech/types.js.map +1 -1
- package/dist/agent/operator-claude.js +8 -0
- package/dist/agent/operator-claude.js.map +1 -1
- package/dist/api/activity-events-endpoint.d.ts +14 -0
- package/dist/api/activity-events-endpoint.js +59 -0
- package/dist/api/activity-events-endpoint.js.map +1 -0
- package/dist/api/bootstrap-endpoint.d.ts +1 -2
- package/dist/api/bootstrap-endpoint.js +42 -24
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/codex-doctor-endpoint.d.ts +22 -5
- package/dist/api/codex-doctor-endpoint.js +136 -17
- package/dist/api/codex-doctor-endpoint.js.map +1 -1
- package/dist/api/debug-report-endpoint.d.ts +27 -0
- package/dist/api/debug-report-endpoint.js +157 -0
- package/dist/api/debug-report-endpoint.js.map +1 -0
- package/dist/api/gather-status.d.ts +33 -0
- package/dist/api/gather-status.js +211 -26
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/hermes-doctor-endpoint.d.ts +15 -7
- package/dist/api/hermes-doctor-endpoint.js +56 -19
- package/dist/api/hermes-doctor-endpoint.js.map +1 -1
- package/dist/api/launcher-status.d.ts +4 -2
- package/dist/api/launcher-status.js +11 -10
- package/dist/api/launcher-status.js.map +1 -1
- package/dist/api/launcher-tasks.d.ts +1 -1
- package/dist/api/launcher-tasks.js +12 -8
- package/dist/api/launcher-tasks.js.map +1 -1
- package/dist/api/operator-artifacts-endpoint.js +73 -6
- package/dist/api/operator-artifacts-endpoint.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +7 -1
- package/dist/api/portfolio-v0-build.js +6 -2
- package/dist/api/portfolio-v0-build.js.map +1 -1
- package/dist/api/prediction-v1-build.d.ts +6 -0
- package/dist/api/prediction-v1-build.js +3 -1
- package/dist/api/prediction-v1-build.js.map +1 -1
- package/dist/api/server.d.ts +17 -0
- package/dist/api/server.js +40 -1
- package/dist/api/server.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +0 -9
- package/dist/api/setup-endpoints.js +11 -153
- package/dist/api/setup-endpoints.js.map +1 -1
- package/dist/api/solvernets-endpoints.js +30 -63
- package/dist/api/solvernets-endpoints.js.map +1 -1
- package/dist/api/status-build.d.ts +115 -2
- package/dist/api/status-build.js +47 -11
- package/dist/api/status-build.js.map +1 -1
- package/dist/api/status-harness-rollup.d.ts +35 -0
- package/dist/api/status-harness-rollup.js +45 -0
- package/dist/api/status-harness-rollup.js.map +1 -0
- package/dist/api/task-runs-build.d.ts +8 -0
- package/dist/api/task-runs-build.js +5 -1
- package/dist/api/task-runs-build.js.map +1 -1
- package/dist/build-info.json +4 -4
- package/dist/build-meta.json +1 -1
- package/dist/captures/live-publisher.js +24 -4
- package/dist/captures/live-publisher.js.map +1 -1
- package/dist/captures/publish.d.ts +1 -1
- package/dist/chain-read-errors.d.ts +12 -0
- package/dist/chain-read-errors.js +26 -1
- package/dist/chain-read-errors.js.map +1 -1
- package/dist/cli/commands/codedigest-revert-check.d.ts +33 -0
- package/dist/cli/commands/codedigest-revert-check.js +249 -0
- package/dist/cli/commands/codedigest-revert-check.js.map +1 -0
- package/dist/cli/commands/solver-nets.d.ts +1 -0
- package/dist/cli/commands/solver-nets.js +177 -22
- package/dist/cli/commands/solver-nets.js.map +1 -1
- package/dist/cli/commands/solver-plugins-block.d.ts +33 -0
- package/dist/cli/commands/solver-plugins-block.js +118 -0
- package/dist/cli/commands/solver-plugins-block.js.map +1 -0
- package/dist/cli/commands/solver-plugins-feedback.d.ts +72 -0
- package/dist/cli/commands/solver-plugins-feedback.js +262 -0
- package/dist/cli/commands/solver-plugins-feedback.js.map +1 -0
- package/dist/cli/commands/solver-plugins-read.d.ts +54 -0
- package/dist/cli/commands/solver-plugins-read.js +259 -0
- package/dist/cli/commands/solver-plugins-read.js.map +1 -0
- package/dist/cli/commands/solver-plugins.d.ts +35 -0
- package/dist/cli/commands/solver-plugins.js +399 -2
- package/dist/cli/commands/solver-plugins.js.map +1 -1
- package/dist/cli/commands/tasks.js +15 -2
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/task-native-readiness.d.ts +7 -0
- package/dist/cli/task-native-readiness.js +7 -5
- package/dist/cli/task-native-readiness.js.map +1 -1
- package/dist/config.d.ts +183 -232
- package/dist/config.js +232 -107
- package/dist/config.js.map +1 -1
- package/dist/daemon/ai-units-gate.d.ts +54 -0
- package/dist/daemon/ai-units-gate.js +82 -0
- package/dist/daemon/ai-units-gate.js.map +1 -0
- package/dist/daemon/creator.js +13 -0
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +10 -0
- package/dist/daemon/daemon.js +203 -30
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/gate-logger.d.ts +9 -0
- package/dist/daemon/gate-logger.js +2 -0
- package/dist/daemon/gate-logger.js.map +1 -0
- package/dist/daemon/jinn-claim-loop.js +22 -4
- package/dist/daemon/jinn-claim-loop.js.map +1 -1
- package/dist/daemon/readiness-gate.d.ts +1 -4
- package/dist/daemon/readiness-gate.js.map +1 -1
- package/dist/daemon/spend-cap-gate.d.ts +40 -0
- package/dist/daemon/spend-cap-gate.js +46 -0
- package/dist/daemon/spend-cap-gate.js.map +1 -0
- package/dist/dashboard/assets/index-CzKxvMcU.css +32 -0
- package/dist/dashboard/assets/index-yVemxHot.js +351 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/discovery/http.js +328 -1
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.js +42 -4
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +129 -0
- package/dist/discovery/types.js.map +1 -1
- package/dist/discovery/with-fallback.js +27 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +8 -3
- package/dist/earning/bootstrap.js +36 -13
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/safe-adapter.js +23 -11
- package/dist/earning/safe-adapter.js.map +1 -1
- package/dist/earning/types.d.ts +6 -6
- package/dist/earning/viem-clients.d.ts +11 -4
- package/dist/earning/viem-clients.js +14 -5
- package/dist/earning/viem-clients.js.map +1 -1
- package/dist/erc8004/identity.d.ts +19 -3
- package/dist/erc8004/identity.js +38 -11
- package/dist/erc8004/identity.js.map +1 -1
- package/dist/erc8004/index.d.ts +1 -1
- package/dist/erc8004/index.js.map +1 -1
- package/dist/events/types.d.ts +2 -2
- package/dist/harnesses/cost-estimates.d.ts +10 -31
- package/dist/harnesses/cost-estimates.js +11 -43
- package/dist/harnesses/cost-estimates.js.map +1 -1
- package/dist/harnesses/engine/engine.d.ts +28 -4
- package/dist/harnesses/engine/engine.js +103 -17
- package/dist/harnesses/engine/engine.js.map +1 -1
- package/dist/harnesses/engine/persistence.d.ts +21 -4
- package/dist/harnesses/engine/persistence.js +43 -6
- package/dist/harnesses/engine/persistence.js.map +1 -1
- package/dist/harnesses/engine/state.d.ts +9 -0
- package/dist/harnesses/engine/state.js +23 -10
- package/dist/harnesses/engine/state.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/bootstrap.js +4 -2
- package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +1 -1
- package/dist/harnesses/impls/hermes-agent/config-builder.js +4 -2
- package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/harness.d.ts +14 -0
- package/dist/harnesses/impls/hermes-agent/harness.js +16 -2
- package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/prompt.d.ts +6 -6
- package/dist/harnesses/impls/hermes-agent/prompt.js +6 -6
- package/dist/harnesses/impls/learner/adapters/claude-code.d.ts +17 -0
- package/dist/harnesses/impls/learner/adapters/claude-code.js +113 -14
- package/dist/harnesses/impls/learner/adapters/claude-code.js.map +1 -1
- package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +9 -0
- package/dist/harnesses/impls/learner/adapters/codex-code.js +30 -8
- package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
- package/dist/harnesses/impls/learner/harness.d.ts +24 -0
- package/dist/harnesses/impls/learner/harness.js +27 -3
- package/dist/harnesses/impls/learner/harness.js.map +1 -1
- package/dist/harnesses/impls/learner/harvest.d.ts +1 -1
- package/dist/harnesses/impls/learner/harvest.js +23 -5
- package/dist/harnesses/impls/learner/harvest.js.map +1 -1
- package/dist/harnesses/impls/learner/restoration-patch.d.ts +2 -2
- package/dist/harnesses/impls/learner/restoration-patch.js +25 -6
- package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +21 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +74 -5
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +103 -32
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
- package/dist/harnesses/readiness-registry.d.ts +7 -0
- package/dist/harnesses/readiness-registry.js +9 -0
- package/dist/harnesses/readiness-registry.js.map +1 -1
- package/dist/learner/revert-decision.d.ts +59 -0
- package/dist/learner/revert-decision.js +53 -0
- package/dist/learner/revert-decision.js.map +1 -0
- package/dist/learner/revert-stats.d.ts +24 -0
- package/dist/learner/revert-stats.js +44 -0
- package/dist/learner/revert-stats.js.map +1 -0
- package/dist/main.js +177 -104
- package/dist/main.js.map +1 -1
- package/dist/mcp/get-codedigest-reward.d.ts +13 -0
- package/dist/mcp/get-codedigest-reward.js +23 -0
- package/dist/mcp/get-codedigest-reward.js.map +1 -0
- package/dist/mcp/server.js +23 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/observability/debug-report-assemble.d.ts +43 -0
- package/dist/observability/debug-report-assemble.js +80 -0
- package/dist/observability/debug-report-assemble.js.map +1 -0
- package/dist/observability/emit-event.d.ts +9 -2
- package/dist/observability/emit-event.js +36 -2
- package/dist/observability/emit-event.js.map +1 -1
- package/dist/observability/file-logger.d.ts +69 -0
- package/dist/observability/file-logger.js +177 -0
- package/dist/observability/file-logger.js.map +1 -0
- package/dist/observability/redact-secrets.d.ts +65 -0
- package/dist/observability/redact-secrets.js +300 -0
- package/dist/observability/redact-secrets.js.map +1 -0
- package/dist/observability/tar.d.ts +30 -0
- package/dist/observability/tar.js +102 -0
- package/dist/observability/tar.js.map +1 -0
- package/dist/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
- package/dist/plugins/learner/skills/learn/promoter-prompt.md +72 -1
- package/dist/preflight/pidfile-liveness.d.ts +44 -0
- package/dist/preflight/pidfile-liveness.js +103 -0
- package/dist/preflight/pidfile-liveness.js.map +1 -0
- package/dist/preflight/rpc-network.d.ts +40 -0
- package/dist/preflight/rpc-network.js +67 -1
- package/dist/preflight/rpc-network.js.map +1 -1
- package/dist/rpc/transport.d.ts +109 -0
- package/dist/rpc/transport.js +220 -0
- package/dist/rpc/transport.js.map +1 -0
- package/dist/scripts/donation-consumption-acceptance.js +7 -28
- package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
- package/dist/scripts/swe-rebench-v2-pytest-missing.json +16 -0
- package/dist/solver-nets/prediction-operator-ux.d.ts +1 -2
- package/dist/solver-nets/prediction-operator-ux.js +56 -53
- package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
- package/dist/solver-nets/registry.d.ts +19 -1
- package/dist/solver-nets/registry.js +37 -24
- package/dist/solver-nets/registry.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-pool.d.ts +9 -2
- package/dist/solver-types/_swe-rebench-v2-pool.js +15 -20
- package/dist/solver-types/_swe-rebench-v2-pool.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-state.d.ts +15 -0
- package/dist/solver-types/_swe-rebench-v2-state.js +19 -0
- package/dist/solver-types/_swe-rebench-v2-state.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +116 -2
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +296 -21
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2-auto.d.ts +20 -11
- package/dist/solver-types/swe-rebench-v2-auto.js +64 -19
- package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2.d.ts +8 -2
- package/dist/solver-types/swe-rebench-v2.js +127 -11
- package/dist/solver-types/swe-rebench-v2.js.map +1 -1
- package/dist/solvernets/daemon-init.d.ts +1 -1
- package/dist/solvernets/daemon-init.js +19 -4
- package/dist/solvernets/daemon-init.js.map +1 -1
- package/dist/solvernets/launched-record-dispatcher.d.ts +4 -0
- package/dist/solvernets/launched-record-dispatcher.js +10 -4
- package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
- package/dist/solvernets/registry-client-erc8004.js +11 -0
- package/dist/solvernets/registry-client-erc8004.js.map +1 -1
- package/dist/solvernets/store.d.ts +2 -2
- package/dist/spend/ai-units-config.d.ts +39 -0
- package/dist/spend/ai-units-config.js +28 -0
- package/dist/spend/ai-units-config.js.map +1 -0
- package/dist/spend/ai-units.d.ts +89 -0
- package/dist/spend/ai-units.js +156 -0
- package/dist/spend/ai-units.js.map +1 -0
- package/dist/spend/cost-surface-status.d.ts +12 -0
- package/dist/spend/cost-surface-status.js +24 -0
- package/dist/spend/cost-surface-status.js.map +1 -0
- package/dist/spend/credential.d.ts +39 -0
- package/dist/spend/credential.js +71 -0
- package/dist/spend/credential.js.map +1 -0
- package/dist/spend/daemon-config.d.ts +13 -0
- package/dist/spend/daemon-config.js +24 -0
- package/dist/spend/daemon-config.js.map +1 -0
- package/dist/spend/pricing.d.ts +16 -0
- package/dist/spend/pricing.js +26 -0
- package/dist/spend/pricing.js.map +1 -0
- package/dist/spend/record.d.ts +13 -0
- package/dist/spend/record.js +36 -0
- package/dist/spend/record.js.map +1 -0
- package/dist/spend/usage.d.ts +27 -0
- package/dist/spend/usage.js +113 -0
- package/dist/spend/usage.js.map +1 -0
- package/dist/store/store.d.ts +101 -0
- package/dist/store/store.js +304 -4
- package/dist/store/store.js.map +1 -1
- package/dist/trajectory/transcript-parsers/codex-session.d.ts +12 -6
- package/dist/trajectory/transcript-parsers/codex-session.js +114 -13
- package/dist/trajectory/transcript-parsers/codex-session.js.map +1 -1
- package/dist/trajectory/transcript-parsers/types.d.ts +8 -8
- package/dist/trajectory/transcript-session-dirs.d.ts +18 -0
- package/dist/trajectory/transcript-session-dirs.js +85 -0
- package/dist/trajectory/transcript-session-dirs.js.map +1 -0
- package/dist/trajectory/transcript-watcher.d.ts +20 -1
- package/dist/trajectory/transcript-watcher.js +108 -32
- package/dist/trajectory/transcript-watcher.js.map +1 -1
- package/dist/tx-retry.d.ts +25 -0
- package/dist/tx-retry.js +95 -7
- package/dist/tx-retry.js.map +1 -1
- package/dist/types/payloads/portfolio-v0.d.ts +3 -3
- package/dist/types/payloads/prediction-apy-v0.d.ts +3 -3
- package/dist/types/payloads/prediction-v0.d.ts +12 -12
- package/package.json +11 -3
- package/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
- package/plugins/learner/skills/learn/promoter-prompt.md +72 -1
- package/plugins/swe-rebench-v2-diffmin/README.md +10 -9
- package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +1 -1
- package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +15 -10
- package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +10 -12
- package/plugins/swe-rebench-v2-runtime/.claude-plugin/plugin.json +1 -1
- package/plugins/swe-rebench-v2-runtime/.codex-plugin/plugin.json +3 -3
- package/plugins/swe-rebench-v2-runtime/README.md +6 -6
- package/plugins/swe-rebench-v2-runtime/jinn.plugin.json +2 -3
- package/plugins/swe-rebench-v2-runtime/skills/task/SKILL.md +81 -0
- package/dist/dashboard/assets/index-BUlE8F3Y.js +0 -330
- package/dist/dashboard/assets/index-blqc7eqq.css +0 -32
- package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +0 -29
- package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +0 -53
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure debug-report bundle assembler (issue #420 §2).
|
|
3
|
+
*
|
|
4
|
+
* Takes already-gathered inputs (status snapshot, resolved config, config
|
|
5
|
+
* provenance, recent activity events, log files, optional screenshot) and
|
|
6
|
+
* produces a redacted `.tar.gz` support bundle. Pure — no I/O, no Store, no
|
|
7
|
+
* HTTP — so it is fully unit-testable. The HTTP endpoint
|
|
8
|
+
* (`api/debug-report-endpoint.ts`) gathers the inputs and calls this.
|
|
9
|
+
*
|
|
10
|
+
* Every JSON file is run through `redactValue` before serialization; log
|
|
11
|
+
* files are already redacted on disk by `FileLogger`, but are re-redacted
|
|
12
|
+
* here defensively (idempotent). The result is safe to share.
|
|
13
|
+
*/
|
|
14
|
+
import { redactValue, buildRedactionReport, REDACTION_VERSION } from './redact-secrets.js';
|
|
15
|
+
import { writeTarGz } from './tar.js';
|
|
16
|
+
/** The set of files a debug-report bundle always contains (relative names). */
|
|
17
|
+
export const DEBUG_REPORT_FILES = [
|
|
18
|
+
'status.json',
|
|
19
|
+
'config.json',
|
|
20
|
+
'config-provenance.json',
|
|
21
|
+
'activity-events.json',
|
|
22
|
+
'redaction-report.md',
|
|
23
|
+
'bundle-meta.json',
|
|
24
|
+
];
|
|
25
|
+
function jsonFile(name, value) {
|
|
26
|
+
return {
|
|
27
|
+
name,
|
|
28
|
+
content: Buffer.from(`${JSON.stringify(redactValue(value), null, 2)}\n`, 'utf8'),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Filesystem-safe ISO timestamp for the bundle directory / filename. */
|
|
32
|
+
export function bundleStamp(generatedAt) {
|
|
33
|
+
return generatedAt.replace(/[:.]/g, '-');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Assemble a redacted `.tar.gz` debug-report bundle. Returns the gzip buffer.
|
|
37
|
+
* Async because the gzip pass is offloaded to the libuv pool (see `writeTarGz`).
|
|
38
|
+
*/
|
|
39
|
+
export async function assembleDebugReport(input) {
|
|
40
|
+
const generatedAt = input.generatedAt ?? new Date().toISOString();
|
|
41
|
+
const root = `jinn-debug-report-${bundleStamp(generatedAt)}`;
|
|
42
|
+
const at = (rel) => `${root}/${rel}`;
|
|
43
|
+
const files = [
|
|
44
|
+
jsonFile(at('status.json'), input.status),
|
|
45
|
+
jsonFile(at('config.json'), input.config),
|
|
46
|
+
jsonFile(at('config-provenance.json'), input.configProvenance),
|
|
47
|
+
jsonFile(at('activity-events.json'), input.activityEvents),
|
|
48
|
+
{
|
|
49
|
+
name: at('redaction-report.md'),
|
|
50
|
+
content: Buffer.from(buildRedactionReport(), 'utf8'),
|
|
51
|
+
},
|
|
52
|
+
jsonFile(at('bundle-meta.json'), {
|
|
53
|
+
schemaVersion: 1,
|
|
54
|
+
generatedAt,
|
|
55
|
+
daemonVersion: input.daemonVersion,
|
|
56
|
+
redactionVersion: REDACTION_VERSION,
|
|
57
|
+
}),
|
|
58
|
+
];
|
|
59
|
+
// Log files — re-redact defensively (FileLogger already redacts on write).
|
|
60
|
+
for (const log of input.logFiles) {
|
|
61
|
+
files.push({
|
|
62
|
+
name: at(`logs/${log.name}`),
|
|
63
|
+
content: Buffer.from(redactValue(log.content.toString('utf8')), 'utf8'),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Screenshot — included verbatim when present, else a clear note.
|
|
67
|
+
if (input.screenshotPng && input.screenshotPng.length > 0) {
|
|
68
|
+
files.push({ name: at('dashboard-screenshot.png'), content: input.screenshotPng });
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
files.push({
|
|
72
|
+
name: at('screenshot-unavailable.txt'),
|
|
73
|
+
content: Buffer.from('No dashboard screenshot was captured. The operator browser either '
|
|
74
|
+
+ 'declined to capture the DOM (content-security policy, very large '
|
|
75
|
+
+ 'page) or the bundle was generated without a browser.\n', 'utf8'),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return await writeTarGz(files);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=debug-report-assemble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-report-assemble.js","sourceRoot":"","sources":["../../src/observability/debug-report-assemble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAgB,MAAM,UAAU,CAAC;AAqBpD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,aAAa;IACb,aAAa;IACb,wBAAwB;IACxB,sBAAsB;IACtB,qBAAqB;IACrB,kBAAkB;CACV,CAAC;AAEX,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAc;IAC5C,OAAO;QACL,IAAI;QACJ,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;KACjF,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAuB;IAC/D,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClE,MAAM,IAAI,GAAG,qBAAqB,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;IAC7D,MAAM,EAAE,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC;IAErD,MAAM,KAAK,GAAc;QACvB,QAAQ,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;QACzC,QAAQ,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;QACzC,QAAQ,CAAC,EAAE,CAAC,wBAAwB,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC;QAC9D,QAAQ,CAAC,EAAE,CAAC,sBAAsB,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC;QAC1D;YACE,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC;YAC/B,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,MAAM,CAAC;SACrD;QACD,QAAQ,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE;YAC/B,aAAa,EAAE,CAAC;YAChB,WAAW;YACX,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,gBAAgB,EAAE,iBAAiB;SACpC,CAAC;KACH,CAAC;IAEF,2EAA2E;IAC3E,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,EAAE,CAAC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YAC5B,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAW,EAAE,MAAM,CAAC;SAClF,CAAC,CAAC;IACL,CAAC;IAED,kEAAkE;IAClE,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,0BAA0B,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,EAAE,CAAC,4BAA4B,CAAC;YACtC,OAAO,EAAE,MAAM,CAAC,IAAI,CAClB,oEAAoE;kBAChE,mEAAmE;kBACnE,wDAAwD,EAC5D,MAAM,CACP;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import type { Store } from '../store/store.js';
|
|
2
|
-
export
|
|
2
|
+
export declare const ALLOWED_LIFECYCLE_KINDS: readonly ["task_posted", "intent_registry_failed", "request_claimed", "delivery_submitted", "evaluation_submitted", "reward_claimed", "balance_topup", "jinn_claim_emitted", "jinn_claim_ticket_recorded", "jinn_claim_submitted", "jinn_claim_canonical_skip", "engine_transition", "tick_error", "race_lost", "spend_cap_reached", "ai_units_cap_reached", "startup", "shutdown"];
|
|
3
|
+
export type LifecycleKind = (typeof ALLOWED_LIFECYCLE_KINDS)[number];
|
|
3
4
|
export interface LifecycleEvent {
|
|
4
5
|
kind: LifecycleKind;
|
|
5
6
|
requestId?: string;
|
|
6
7
|
serviceIndex?: number;
|
|
7
8
|
txHash?: string;
|
|
8
9
|
solverType?: string;
|
|
9
|
-
outcome?: 'ok' | 'failed' | 'warn';
|
|
10
|
+
outcome?: 'ok' | 'failed' | 'warn' | 'paused';
|
|
10
11
|
detail?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional: when set, written to the row's `credential_id` column. The
|
|
14
|
+
* AI-units cap-reached event uses this so cross-restart memo hydration
|
|
15
|
+
* can query by credential (issue #815).
|
|
16
|
+
*/
|
|
17
|
+
credentialId?: string;
|
|
11
18
|
}
|
|
12
19
|
export declare function emitEvent(store: Store, event: LifecycleEvent, component?: string): void;
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
import { getFileLogger } from './file-logger.js';
|
|
2
|
+
export const ALLOWED_LIFECYCLE_KINDS = [
|
|
3
|
+
'task_posted',
|
|
4
|
+
'intent_registry_failed',
|
|
5
|
+
'request_claimed',
|
|
6
|
+
'delivery_submitted',
|
|
7
|
+
'evaluation_submitted',
|
|
8
|
+
'reward_claimed',
|
|
9
|
+
'balance_topup',
|
|
10
|
+
'jinn_claim_emitted',
|
|
11
|
+
'jinn_claim_ticket_recorded',
|
|
12
|
+
'jinn_claim_submitted',
|
|
13
|
+
'jinn_claim_canonical_skip',
|
|
14
|
+
'engine_transition',
|
|
15
|
+
'tick_error',
|
|
16
|
+
'race_lost',
|
|
17
|
+
'spend_cap_reached',
|
|
18
|
+
'ai_units_cap_reached',
|
|
19
|
+
'startup',
|
|
20
|
+
'shutdown',
|
|
21
|
+
];
|
|
1
22
|
export function emitEvent(store, event, component = 'lifecycle') {
|
|
2
23
|
const ts = new Date().toISOString();
|
|
3
24
|
store.recordActivityEvent({
|
|
@@ -9,10 +30,13 @@ export function emitEvent(store, event, component = 'lifecycle') {
|
|
|
9
30
|
solverType: event.solverType ?? null,
|
|
10
31
|
outcome: event.outcome ?? null,
|
|
11
32
|
detail: event.detail ?? null,
|
|
33
|
+
credentialId: event.credentialId ?? null,
|
|
12
34
|
});
|
|
13
35
|
const payload = {
|
|
14
36
|
ts,
|
|
15
|
-
level: event.outcome === 'failed' ? 'error'
|
|
37
|
+
level: event.outcome === 'failed' ? 'error'
|
|
38
|
+
: (event.outcome === 'warn' || event.outcome === 'paused') ? 'warn'
|
|
39
|
+
: 'info',
|
|
16
40
|
component,
|
|
17
41
|
msg: event.detail ?? event.kind,
|
|
18
42
|
requestId: event.requestId ?? null,
|
|
@@ -22,6 +46,16 @@ export function emitEvent(store, event, component = 'lifecycle') {
|
|
|
22
46
|
outcome: event.outcome ?? 'ok',
|
|
23
47
|
kind: event.kind,
|
|
24
48
|
};
|
|
25
|
-
|
|
49
|
+
const line = JSON.stringify(payload);
|
|
50
|
+
process.stderr.write(`${line}\n`);
|
|
51
|
+
// Issue #420: tee every lifecycle event into the rotating daemon file
|
|
52
|
+
// logger so the one-click debug report has durable, pre-redacted logs.
|
|
53
|
+
// Best-effort — a logging failure must never affect event emission.
|
|
54
|
+
try {
|
|
55
|
+
getFileLogger().write(line);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* ignore */
|
|
59
|
+
}
|
|
26
60
|
}
|
|
27
61
|
//# sourceMappingURL=emit-event.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-event.js","sourceRoot":"","sources":["../../src/observability/emit-event.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"emit-event.js","sourceRoot":"","sources":["../../src/observability/emit-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,aAAa;IACb,wBAAwB;IACxB,iBAAiB;IACjB,oBAAoB;IACpB,sBAAsB;IACtB,gBAAgB;IAChB,eAAe;IACf,oBAAoB;IACpB,4BAA4B;IAC5B,sBAAsB;IACtB,2BAA2B;IAC3B,mBAAmB;IACnB,YAAY;IACZ,WAAW;IACX,mBAAmB;IACnB,sBAAsB;IACtB,SAAS;IACT,UAAU;CACF,CAAC;AAoBX,MAAM,UAAU,SAAS,CACvB,KAAY,EACZ,KAAqB,EACrB,SAAS,GAAG,WAAW;IAEvB,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,KAAK,CAAC,mBAAmB,CAAC;QACxB,EAAE;QACF,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;QACxC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;QACpC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;QAC5B,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;KACzC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG;QACd,EAAE;QACF,KAAK,EAAE,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO;YACzC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM;gBACnE,CAAC,CAAC,MAAM;QACV,SAAS;QACT,GAAG,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI;QAC/B,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;QAC5B,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI;QACxC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;QACpC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IAElC,sEAAsE;IACtE,uEAAuE;IACvE,oEAAoE;IACpE,IAAI,CAAC;QACH,aAAa,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rotating, size-bounded daemon file logger (issue #420 §1).
|
|
3
|
+
*
|
|
4
|
+
* The daemon's logging today is unstructured and ephemeral — `console.*` to
|
|
5
|
+
* stdout/stderr, nothing durable. A support bundle needs durable logs, so
|
|
6
|
+
* this module appends a redacted log line per call to `~/.jinn-client/logs/`,
|
|
7
|
+
* rotates the active file when it crosses a size bound, and prunes both by
|
|
8
|
+
* file count and by age.
|
|
9
|
+
*
|
|
10
|
+
* Hand-rolled rather than pulling in a logging framework: a size-bounded
|
|
11
|
+
* rotator is ~120 lines and self-contained, and the bundle assembler only
|
|
12
|
+
* needs `listLogFiles()` to enumerate the rotation set.
|
|
13
|
+
*
|
|
14
|
+
* Redaction at write time: every line is run through `redactValue`'s string
|
|
15
|
+
* redactor before it hits disk, so the on-disk file is safe by construction
|
|
16
|
+
* and the bundle assembler does not need to re-scan log bytes.
|
|
17
|
+
*/
|
|
18
|
+
export interface FileLoggerOptions {
|
|
19
|
+
/** Log directory. Defaults to `~/.jinn-client/logs`. */
|
|
20
|
+
logDir?: string;
|
|
21
|
+
/** Rotate the active file once it crosses this many bytes. Default 5 MiB. */
|
|
22
|
+
maxBytes?: number;
|
|
23
|
+
/** Number of files to keep, including the active `daemon.log`. Default 5. */
|
|
24
|
+
maxFiles?: number;
|
|
25
|
+
/** Delete rotated files older than this many days on startup. Default 14. */
|
|
26
|
+
maxAgeDays?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare class FileLogger {
|
|
29
|
+
private readonly logDir;
|
|
30
|
+
private readonly maxBytes;
|
|
31
|
+
private readonly maxFiles;
|
|
32
|
+
private readonly maxAgeDays;
|
|
33
|
+
private readonly activePath;
|
|
34
|
+
private bytesWritten;
|
|
35
|
+
private closed;
|
|
36
|
+
constructor(opts?: FileLoggerOptions);
|
|
37
|
+
/**
|
|
38
|
+
* Append a single log line. The line is redacted before it hits disk.
|
|
39
|
+
*
|
|
40
|
+
* Writes synchronously (`appendFileSync`) rather than via a `WriteStream`:
|
|
41
|
+
* a daemon emits at most a handful of lines per second, and a synchronous
|
|
42
|
+
* append avoids buffering races on shutdown / rotation.
|
|
43
|
+
*/
|
|
44
|
+
write(line: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Ordered list of log files for the bundle assembler: the active
|
|
47
|
+
* `daemon.log` first, then `daemon.log.1`, `.2`, ... in age order.
|
|
48
|
+
* Only files that exist on disk are returned.
|
|
49
|
+
*/
|
|
50
|
+
listLogFiles(): string[];
|
|
51
|
+
/** Mark the logger closed for clean daemon shutdown. */
|
|
52
|
+
close(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Rotate: `daemon.log.{N-1}` -> `.N` shift (oldest dropped), then
|
|
55
|
+
* `daemon.log` -> `daemon.log.1`. The next `write` recreates the active
|
|
56
|
+
* file via `appendFileSync`.
|
|
57
|
+
*/
|
|
58
|
+
private rotate;
|
|
59
|
+
/** Delete rotated `daemon.log.*` files older than the age bound. */
|
|
60
|
+
private sweepStaleFiles;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Process-wide file logger singleton. Mirrors `events/emitter.ts`'s
|
|
64
|
+
* `getEventBuffer()` pattern. Lazily constructed on first use so importing
|
|
65
|
+
* this module never touches the filesystem.
|
|
66
|
+
*/
|
|
67
|
+
export declare function getFileLogger(): FileLogger;
|
|
68
|
+
/** Close the singleton logger (daemon shutdown). Safe to call when unset. */
|
|
69
|
+
export declare function closeFileLogger(): void;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rotating, size-bounded daemon file logger (issue #420 §1).
|
|
3
|
+
*
|
|
4
|
+
* The daemon's logging today is unstructured and ephemeral — `console.*` to
|
|
5
|
+
* stdout/stderr, nothing durable. A support bundle needs durable logs, so
|
|
6
|
+
* this module appends a redacted log line per call to `~/.jinn-client/logs/`,
|
|
7
|
+
* rotates the active file when it crosses a size bound, and prunes both by
|
|
8
|
+
* file count and by age.
|
|
9
|
+
*
|
|
10
|
+
* Hand-rolled rather than pulling in a logging framework: a size-bounded
|
|
11
|
+
* rotator is ~120 lines and self-contained, and the bundle assembler only
|
|
12
|
+
* needs `listLogFiles()` to enumerate the rotation set.
|
|
13
|
+
*
|
|
14
|
+
* Redaction at write time: every line is run through `redactValue`'s string
|
|
15
|
+
* redactor before it hits disk, so the on-disk file is safe by construction
|
|
16
|
+
* and the bundle assembler does not need to re-scan log bytes.
|
|
17
|
+
*/
|
|
18
|
+
import { appendFileSync, existsSync, mkdirSync, renameSync, statSync, unlinkSync, readdirSync, } from 'node:fs';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { redactValue } from './redact-secrets.js';
|
|
22
|
+
const DEFAULT_MAX_BYTES = 5 * 1024 * 1024;
|
|
23
|
+
const DEFAULT_MAX_FILES = 5;
|
|
24
|
+
const DEFAULT_MAX_AGE_DAYS = 14;
|
|
25
|
+
const ACTIVE_FILE = 'daemon.log';
|
|
26
|
+
/** Redact a single log line — strips secret-shaped substrings. */
|
|
27
|
+
function redactLine(line) {
|
|
28
|
+
return redactValue(line);
|
|
29
|
+
}
|
|
30
|
+
export class FileLogger {
|
|
31
|
+
logDir;
|
|
32
|
+
maxBytes;
|
|
33
|
+
maxFiles;
|
|
34
|
+
maxAgeDays;
|
|
35
|
+
activePath;
|
|
36
|
+
bytesWritten = 0;
|
|
37
|
+
closed = false;
|
|
38
|
+
constructor(opts = {}) {
|
|
39
|
+
this.logDir = opts.logDir ?? join(homedir(), '.jinn-client', 'logs');
|
|
40
|
+
this.maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
41
|
+
this.maxFiles = opts.maxFiles ?? DEFAULT_MAX_FILES;
|
|
42
|
+
this.maxAgeDays = opts.maxAgeDays ?? DEFAULT_MAX_AGE_DAYS;
|
|
43
|
+
this.activePath = join(this.logDir, ACTIVE_FILE);
|
|
44
|
+
mkdirSync(this.logDir, { recursive: true });
|
|
45
|
+
this.sweepStaleFiles();
|
|
46
|
+
this.bytesWritten = existsSync(this.activePath)
|
|
47
|
+
? statSync(this.activePath).size
|
|
48
|
+
: 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Append a single log line. The line is redacted before it hits disk.
|
|
52
|
+
*
|
|
53
|
+
* Writes synchronously (`appendFileSync`) rather than via a `WriteStream`:
|
|
54
|
+
* a daemon emits at most a handful of lines per second, and a synchronous
|
|
55
|
+
* append avoids buffering races on shutdown / rotation.
|
|
56
|
+
*/
|
|
57
|
+
write(line) {
|
|
58
|
+
if (this.closed)
|
|
59
|
+
return;
|
|
60
|
+
const safe = `${redactLine(line)}\n`;
|
|
61
|
+
const size = Buffer.byteLength(safe);
|
|
62
|
+
if (this.bytesWritten > 0 && this.bytesWritten + size > this.maxBytes) {
|
|
63
|
+
this.rotate();
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
appendFileSync(this.activePath, safe);
|
|
67
|
+
this.bytesWritten += size;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Logging must never crash the daemon.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Ordered list of log files for the bundle assembler: the active
|
|
75
|
+
* `daemon.log` first, then `daemon.log.1`, `.2`, ... in age order.
|
|
76
|
+
* Only files that exist on disk are returned.
|
|
77
|
+
*/
|
|
78
|
+
listLogFiles() {
|
|
79
|
+
const out = [];
|
|
80
|
+
if (existsSync(this.activePath))
|
|
81
|
+
out.push(this.activePath);
|
|
82
|
+
for (let i = 1; i < this.maxFiles; i++) {
|
|
83
|
+
const p = `${this.activePath}.${i}`;
|
|
84
|
+
if (existsSync(p))
|
|
85
|
+
out.push(p);
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
/** Mark the logger closed for clean daemon shutdown. */
|
|
90
|
+
close() {
|
|
91
|
+
this.closed = true;
|
|
92
|
+
}
|
|
93
|
+
// ── internals ──────────────────────────────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Rotate: `daemon.log.{N-1}` -> `.N` shift (oldest dropped), then
|
|
96
|
+
* `daemon.log` -> `daemon.log.1`. The next `write` recreates the active
|
|
97
|
+
* file via `appendFileSync`.
|
|
98
|
+
*/
|
|
99
|
+
rotate() {
|
|
100
|
+
// Drop the oldest rotated file.
|
|
101
|
+
const oldest = `${this.activePath}.${this.maxFiles - 1}`;
|
|
102
|
+
if (existsSync(oldest)) {
|
|
103
|
+
try {
|
|
104
|
+
unlinkSync(oldest);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
/* ignore */
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Shift `.i` -> `.i+1` from oldest to newest.
|
|
111
|
+
for (let i = this.maxFiles - 2; i >= 1; i--) {
|
|
112
|
+
const from = `${this.activePath}.${i}`;
|
|
113
|
+
const to = `${this.activePath}.${i + 1}`;
|
|
114
|
+
if (existsSync(from)) {
|
|
115
|
+
try {
|
|
116
|
+
renameSync(from, to);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
/* ignore */
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Active -> .1.
|
|
124
|
+
if (existsSync(this.activePath)) {
|
|
125
|
+
try {
|
|
126
|
+
renameSync(this.activePath, `${this.activePath}.1`);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
/* ignore */
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
this.bytesWritten = 0;
|
|
133
|
+
}
|
|
134
|
+
/** Delete rotated `daemon.log.*` files older than the age bound. */
|
|
135
|
+
sweepStaleFiles() {
|
|
136
|
+
const cutoffMs = Date.now() - this.maxAgeDays * 24 * 60 * 60 * 1000;
|
|
137
|
+
let entries;
|
|
138
|
+
try {
|
|
139
|
+
entries = readdirSync(this.logDir);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
for (const entry of entries) {
|
|
145
|
+
if (!/^daemon\.log\.\d+$/.test(entry))
|
|
146
|
+
continue;
|
|
147
|
+
const p = join(this.logDir, entry);
|
|
148
|
+
try {
|
|
149
|
+
if (statSync(p).mtimeMs < cutoffMs) {
|
|
150
|
+
unlinkSync(p);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
/* ignore */
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// ── module singleton ─────────────────────────────────────────────────────────
|
|
160
|
+
let SINGLETON = null;
|
|
161
|
+
/**
|
|
162
|
+
* Process-wide file logger singleton. Mirrors `events/emitter.ts`'s
|
|
163
|
+
* `getEventBuffer()` pattern. Lazily constructed on first use so importing
|
|
164
|
+
* this module never touches the filesystem.
|
|
165
|
+
*/
|
|
166
|
+
export function getFileLogger() {
|
|
167
|
+
if (!SINGLETON) {
|
|
168
|
+
SINGLETON = new FileLogger();
|
|
169
|
+
}
|
|
170
|
+
return SINGLETON;
|
|
171
|
+
}
|
|
172
|
+
/** Close the singleton logger (daemon shutdown). Safe to call when unset. */
|
|
173
|
+
export function closeFileLogger() {
|
|
174
|
+
SINGLETON?.close();
|
|
175
|
+
SINGLETON = null;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=file-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-logger.js","sourceRoot":"","sources":["../../src/observability/file-logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security-critical redaction for the one-click operator debug report
|
|
3
|
+
* (issue #420 §4).
|
|
4
|
+
*
|
|
5
|
+
* Single source of truth for stripping secrets from anything that lands in a
|
|
6
|
+
* support bundle or an on-disk log file. Reuses the existing redaction
|
|
7
|
+
* primitives (`trajectory/secret-scrub.ts`, `util/redact-rpc-urls.ts`) and
|
|
8
|
+
* extends them with the secret surfaces enumerated in the issue:
|
|
9
|
+
*
|
|
10
|
+
* - keystore password / JINN_PASSWORD
|
|
11
|
+
* - private keys / mnemonics / seed phrases
|
|
12
|
+
* - daemon API token / UI token / handshake key
|
|
13
|
+
* - harness API keys (Anthropic / OpenAI / OpenRouter / Nous Portal)
|
|
14
|
+
* - RPC URLs with embedded credential segments
|
|
15
|
+
*
|
|
16
|
+
* Two redaction layers run together:
|
|
17
|
+
* 1. key-name redaction — values of keys matching a secret-name pattern.
|
|
18
|
+
* 2. string-shape redaction — values that *look* like a secret (a bare
|
|
19
|
+
* 0x-64 hex string, a JWT) regardless of their key name.
|
|
20
|
+
*
|
|
21
|
+
* Wallet addresses (0x-40), RPC hostnames/paths, contract/deployment
|
|
22
|
+
* addresses and file paths are intentionally KEPT — they are public or
|
|
23
|
+
* needed to reproduce a network issue. See `buildRedactionReport`.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Bumped whenever the redaction logic changes in a way that affects what is
|
|
27
|
+
* stripped. Recorded in `bundle-meta.json` so a bundle can be read against
|
|
28
|
+
* the redaction rules that produced it.
|
|
29
|
+
*/
|
|
30
|
+
export declare const REDACTION_VERSION = "2";
|
|
31
|
+
/**
|
|
32
|
+
* Keep the host (and a coarse path shape) of an RPC URL but strip any
|
|
33
|
+
* embedded credential: userinfo, `/v3/<key>`-style key segments, and
|
|
34
|
+
* `?key=`/`?apikey=`-style query credentials.
|
|
35
|
+
*
|
|
36
|
+
* RPC URLs are intentionally kept in the bundle (per the issue's acceptance
|
|
37
|
+
* criteria) so a network issue can be reproduced — only the secret part is
|
|
38
|
+
* removed.
|
|
39
|
+
*/
|
|
40
|
+
export declare function redactRpcUrl(url: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Deep-clone `value` and redact every secret it contains. Pure — the input is
|
|
43
|
+
* never mutated.
|
|
44
|
+
*
|
|
45
|
+
* - Object keys matching a secret-name pattern -> value replaced with a marker.
|
|
46
|
+
* - Object keys holding an RPC URL -> value run through `redactRpcUrl`.
|
|
47
|
+
* - Object keys holding a public on-chain identifier (request id / tx hash) ->
|
|
48
|
+
* value kept verbatim, exempt from string-shape `hex64` redaction.
|
|
49
|
+
* - Any other string value -> secret-shaped substrings stripped.
|
|
50
|
+
* - Arrays and nested objects are walked recursively.
|
|
51
|
+
*/
|
|
52
|
+
export declare function redactValue(value: unknown): unknown;
|
|
53
|
+
/**
|
|
54
|
+
* Redact a resolved `JinnConfig` for inclusion in the bundle. Thin wrapper
|
|
55
|
+
* over `redactValue` — the deep walk already handles every secret surface,
|
|
56
|
+
* including `rpcUrl`, nested `ui.token`/`ui.handshakeKey`, and any future
|
|
57
|
+
* config key matching a secret-name pattern.
|
|
58
|
+
*/
|
|
59
|
+
export declare function redactConfig(config: unknown): unknown;
|
|
60
|
+
/**
|
|
61
|
+
* Generate `redaction-report.md` — the human-readable record of what the
|
|
62
|
+
* debug-report bundle strips and what it intentionally keeps. This file is
|
|
63
|
+
* the "redaction coverage documented" acceptance criterion for issue #420.
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildRedactionReport(): string;
|