toolnet-memory 0.2.0 → 0.2.2
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 +443 -70
- package/bin/toolnet-memory +66 -53
- package/bundle/agy.js +88 -0
- package/bundle/codex.js +92 -0
- package/bundle/context-runtime.js +56 -0
- package/bundle/context.js +62 -0
- package/bundle/doctor.js +3 -0
- package/bundle/full-index.js +8 -0
- package/bundle/learner.js +8 -0
- package/bundle/mcp.js +7 -0
- package/bundle/opencode.js +314 -0
- package/bundle/project-manual.js +54 -0
- package/bundle/setup.js +31 -0
- package/bundle/snapshot.js +4 -0
- package/bundle/work-continuity.js +12 -0
- package/package.json +11 -5
- package/dist/packages/cli/commands.js +0 -1
- package/dist/packages/cli/index.js +0 -1
- package/dist/packages/sdk/client.js +0 -78
- package/dist/packages/sdk/index.js +0 -1
- package/dist/packages/sdk/types.js +0 -1
- package/dist/src/api/index.js +0 -1
- package/dist/src/api/routes/health.js +0 -1
- package/dist/src/api/routes/index.js +0 -1
- package/dist/src/api/routes/memory.js +0 -1
- package/dist/src/api/routes/projects.js +0 -1
- package/dist/src/api/routes/search.js +0 -1
- package/dist/src/api/server.js +0 -1
- package/dist/src/capture/activity-capture.js +0 -21
- package/dist/src/capture/command-capture.js +0 -12
- package/dist/src/capture/error-capture.js +0 -14
- package/dist/src/capture/event-deduplicator.js +0 -28
- package/dist/src/capture/event-queue.js +0 -20
- package/dist/src/capture/file-capture.js +0 -23
- package/dist/src/capture/index.js +0 -8
- package/dist/src/capture/session-capture.js +0 -18
- package/dist/src/capture/tool-capture.js +0 -13
- package/dist/src/code-intelligence/analysis/analysis-engine.js +0 -26
- package/dist/src/code-intelligence/analysis/dead-code-analyzer.js +0 -127
- package/dist/src/code-intelligence/analysis/dependency-analyzer.js +0 -66
- package/dist/src/code-intelligence/analysis/index.js +0 -4
- package/dist/src/code-intelligence/analysis/types.js +0 -1
- package/dist/src/code-intelligence/architecture/architecture-engine.js +0 -48
- package/dist/src/code-intelligence/architecture/clusters.js +0 -322
- package/dist/src/code-intelligence/architecture/entry-points.js +0 -150
- package/dist/src/code-intelligence/architecture/hotspots.js +0 -136
- package/dist/src/code-intelligence/architecture/index.js +0 -6
- package/dist/src/code-intelligence/architecture/layers.js +0 -197
- package/dist/src/code-intelligence/architecture/types.js +0 -1
- package/dist/src/code-intelligence/chunks/index.js +0 -2
- package/dist/src/code-intelligence/chunks/smart-chunker.js +0 -125
- package/dist/src/code-intelligence/chunks/types.js +0 -1
- package/dist/src/code-intelligence/git/git-diff.js +0 -109
- package/dist/src/code-intelligence/git/index.js +0 -1
- package/dist/src/code-intelligence/graph/architecture.js +0 -26
- package/dist/src/code-intelligence/graph/graph-builder.js +0 -213
- package/dist/src/code-intelligence/graph/graph-store.js +0 -57
- package/dist/src/code-intelligence/graph/index.js +0 -1
- package/dist/src/code-intelligence/graph/relationships.js +0 -1
- package/dist/src/code-intelligence/graph/trace.js +0 -65
- package/dist/src/code-intelligence/impact/blast-radius.js +0 -160
- package/dist/src/code-intelligence/impact/change-mapper.js +0 -69
- package/dist/src/code-intelligence/impact/edit-tool-detector.js +0 -92
- package/dist/src/code-intelligence/impact/impact-analyzer.js +0 -60
- package/dist/src/code-intelligence/impact/impact-guard.js +0 -33
- package/dist/src/code-intelligence/impact/index.js +0 -5
- package/dist/src/code-intelligence/incremental/file-hash.js +0 -8
- package/dist/src/code-intelligence/incremental/incremental-indexer.js +0 -106
- package/dist/src/code-intelligence/incremental/manifest-builder.js +0 -19
- package/dist/src/code-intelligence/incremental/manifest.js +0 -31
- package/dist/src/code-intelligence/index.js +0 -23
- package/dist/src/code-intelligence/indexer/file-watcher.js +0 -1
- package/dist/src/code-intelligence/indexer/incremental-indexer.js +0 -1
- package/dist/src/code-intelligence/indexer/index.js +0 -1
- package/dist/src/code-intelligence/indexer/repository-indexer.js +0 -31
- package/dist/src/code-intelligence/indexer/repository-scanner.js +0 -50
- package/dist/src/code-intelligence/parsers/index.js +0 -1
- package/dist/src/code-intelligence/parsers/tree-sitter/index.js +0 -1
- package/dist/src/code-intelligence/parsers/tree-sitter/languages.js +0 -1
- package/dist/src/code-intelligence/parsers/tree-sitter/parser.js +0 -1
- package/dist/src/code-intelligence/parsers/typescript-parser.js +0 -190
- package/dist/src/code-intelligence/query/graph-query-engine.js +0 -275
- package/dist/src/code-intelligence/query/index.js +0 -2
- package/dist/src/code-intelligence/query/types.js +0 -1
- package/dist/src/code-intelligence/resolution/index.js +0 -2
- package/dist/src/code-intelligence/resolution/types.js +0 -1
- package/dist/src/code-intelligence/resolution/typescript-resolver.js +0 -316
- package/dist/src/code-intelligence/rich/index.js +0 -1
- package/dist/src/code-intelligence/rich/rich-graph-enricher.js +0 -463
- package/dist/src/code-intelligence/semantic/index.js +0 -2
- package/dist/src/code-intelligence/semantic/semantic-code-engine.js +0 -213
- package/dist/src/code-intelligence/semantic/source-priority.js +0 -22
- package/dist/src/code-intelligence/symbols/index.js +0 -1
- package/dist/src/code-intelligence/symbols/reference-resolver.js +0 -21
- package/dist/src/code-intelligence/symbols/symbol-extractor.js +0 -1
- package/dist/src/code-intelligence/test-analysis.js +0 -72
- package/dist/src/code-intelligence/test-architecture.js +0 -67
- package/dist/src/code-intelligence/test-impact.js +0 -47
- package/dist/src/code-intelligence/test-incremental.js +0 -24
- package/dist/src/code-intelligence/test-index.js +0 -39
- package/dist/src/code-intelligence/test-resolution.js +0 -54
- package/dist/src/code-intelligence/test-rich-graph.js +0 -48
- package/dist/src/code-intelligence/test-semantic.js +0 -57
- package/dist/src/code-intelligence/test-visualization.js +0 -36
- package/dist/src/code-intelligence/types.js +0 -1
- package/dist/src/code-intelligence/visualization/index.js +0 -2
- package/dist/src/code-intelligence/visualization/types.js +0 -1
- package/dist/src/code-intelligence/visualization/visualization-builder.js +0 -104
- package/dist/src/core/config.js +0 -66
- package/dist/src/core/global-env.js +0 -70
- package/dist/src/core/importance.js +0 -30
- package/dist/src/core/index.js +0 -5
- package/dist/src/core/memory-engine.js +0 -183
- package/dist/src/core/project-manager.js +0 -243
- package/dist/src/core/types.js +0 -1
- package/dist/src/embeddings/batch-embedder.js +0 -1
- package/dist/src/embeddings/cache.js +0 -1
- package/dist/src/embeddings/embedder.js +0 -51
- package/dist/src/embeddings/index.js +0 -4
- package/dist/src/embeddings/local.js +0 -37
- package/dist/src/embeddings/provider.js +0 -1
- package/dist/src/embeddings/remote.js +0 -76
- package/dist/src/embeddings/test-connection.js +0 -16
- package/dist/src/hooks/after-edit.js +0 -3
- package/dist/src/hooks/after-tool.js +0 -3
- package/dist/src/hooks/auto-context.js +0 -68
- package/dist/src/hooks/auto-impact-guard.js +0 -94
- package/dist/src/hooks/auto-retrieval.js +0 -27
- package/dist/src/hooks/before-agent.js +0 -18
- package/dist/src/hooks/before-compact.js +0 -3
- package/dist/src/hooks/before-edit.js +0 -20
- package/dist/src/hooks/index.js +0 -11
- package/dist/src/hooks/runtime.js +0 -110
- package/dist/src/hooks/session-end.js +0 -3
- package/dist/src/hooks/session-start.js +0 -3
- package/dist/src/index.js +0 -22
- package/dist/src/mcp/bootstrap.js +0 -68
- package/dist/src/mcp/context.js +0 -1
- package/dist/src/mcp/index.js +0 -3
- package/dist/src/mcp/server.js +0 -45
- package/dist/src/mcp/tools/analyze-impact.js +0 -41
- package/dist/src/mcp/tools/dead-code.js +0 -55
- package/dist/src/mcp/tools/find-callers.js +0 -24
- package/dist/src/mcp/tools/find-dependencies.js +0 -57
- package/dist/src/mcp/tools/find-symbol.js +0 -7
- package/dist/src/mcp/tools/get-architecture.js +0 -11
- package/dist/src/mcp/tools/graph-dependents.js +0 -24
- package/dist/src/mcp/tools/graph-neighborhood.js +0 -58
- package/dist/src/mcp/tools/graph-path.js +0 -43
- package/dist/src/mcp/tools/graph-query-utils.js +0 -32
- package/dist/src/mcp/tools/impact-guard.js +0 -34
- package/dist/src/mcp/tools/index-repository.js +0 -1
- package/dist/src/mcp/tools/index.js +0 -20
- package/dist/src/mcp/tools/memory-decisions.js +0 -1
- package/dist/src/mcp/tools/memory-forget.js +0 -14
- package/dist/src/mcp/tools/memory-recent.js +0 -1
- package/dist/src/mcp/tools/memory-remember.js +0 -33
- package/dist/src/mcp/tools/memory-rules.js +0 -1
- package/dist/src/mcp/tools/memory-search.js +0 -18
- package/dist/src/mcp/tools/memory-todos.js +0 -1
- package/dist/src/mcp/tools/project-context.js +0 -25
- package/dist/src/mcp/tools/search-code.js +0 -21
- package/dist/src/mcp/tools/semantic-code-search.js +0 -33
- package/dist/src/mcp/tools/snapshot-create.js +0 -13
- package/dist/src/mcp/tools/snapshot-list.js +0 -7
- package/dist/src/mcp/tools/snapshot-restore.js +0 -13
- package/dist/src/mcp/tools/trace-calls.js +0 -37
- package/dist/src/memory/activity.js +0 -5
- package/dist/src/memory/conflict-detector.js +0 -105
- package/dist/src/memory/consolidator.js +0 -104
- package/dist/src/memory/decay.js +0 -59
- package/dist/src/memory/decisions.js +0 -3
- package/dist/src/memory/deduplicate.js +0 -25
- package/dist/src/memory/index.js +0 -11
- package/dist/src/memory/maintenance.js +0 -16
- package/dist/src/memory/remember.js +0 -3
- package/dist/src/memory/rules.js +0 -3
- package/dist/src/memory/search.js +0 -3
- package/dist/src/memory/summaries.js +0 -1
- package/dist/src/memory/todos.js +0 -3
- package/dist/src/processor/decision-extractor.js +0 -13
- package/dist/src/processor/importance-scorer.js +0 -22
- package/dist/src/processor/index.js +0 -7
- package/dist/src/processor/memory-extractor.js +0 -59
- package/dist/src/processor/memory-processor.js +0 -105
- package/dist/src/processor/rule-extractor.js +0 -13
- package/dist/src/processor/summarizer.js +0 -71
- package/dist/src/processor/todo-extractor.js +0 -12
- package/dist/src/production/config-check.js +0 -34
- package/dist/src/production/doctor.js +0 -58
- package/dist/src/production/full-index.js +0 -114
- package/dist/src/production/health.js +0 -58
- package/dist/src/production/index-pipeline.js +0 -151
- package/dist/src/production/index.js +0 -4
- package/dist/src/production/project-lock.js +0 -95
- package/dist/src/production/project-status.js +0 -16
- package/dist/src/production/recovery.js +0 -15
- package/dist/src/production/snapshot-cli.js +0 -58
- package/dist/src/project-manual/cli.js +0 -77
- package/dist/src/project-manual/index.js +0 -2
- package/dist/src/project-manual/manager.js +0 -147
- package/dist/src/project-manual/types.js +0 -1
- package/dist/src/retrieval/bm25/index.js +0 -1
- package/dist/src/retrieval/bm25/search.js +0 -1
- package/dist/src/retrieval/bm25.js +0 -30
- package/dist/src/retrieval/context-budget.js +0 -1
- package/dist/src/retrieval/context-builder.js +0 -22
- package/dist/src/retrieval/graph/index.js +0 -1
- package/dist/src/retrieval/graph/search.js +0 -1
- package/dist/src/retrieval/hybrid/hybrid-search.js +0 -1
- package/dist/src/retrieval/hybrid/index.js +0 -1
- package/dist/src/retrieval/hybrid-search.js +0 -68
- package/dist/src/retrieval/importance.js +0 -16
- package/dist/src/retrieval/index.js +0 -12
- package/dist/src/retrieval/query-analyzer.js +0 -32
- package/dist/src/retrieval/query-classifier.js +0 -1
- package/dist/src/retrieval/query-expansion.js +0 -1
- package/dist/src/retrieval/recency.js +0 -12
- package/dist/src/retrieval/reranker/index.js +0 -1
- package/dist/src/retrieval/reranker/reranker.js +0 -1
- package/dist/src/retrieval/retrieval-engine.js +0 -17
- package/dist/src/retrieval/tokenizer.js +0 -9
- package/dist/src/retrieval/type-priority.js +0 -10
- package/dist/src/retrieval/types.js +0 -1
- package/dist/src/retrieval/vector/index.js +0 -4
- package/dist/src/retrieval/vector/metadata-filter.js +0 -1
- package/dist/src/retrieval/vector/persistence.js +0 -67
- package/dist/src/retrieval/vector/search.js +0 -12
- package/dist/src/retrieval/vector/test-persistence.js +0 -36
- package/dist/src/retrieval/vector/upsert.js +0 -40
- package/dist/src/retrieval/vector/vector-store.js +0 -89
- package/dist/src/retrieval/vector-hybrid-engine.js +0 -91
- package/dist/src/runtime/bootstrap.js +0 -28
- package/dist/src/runtime/graceful.js +0 -17
- package/dist/src/runtime/index.js +0 -3
- package/dist/src/runtime/toolnet-memory-runtime.js +0 -156
- package/dist/src/security/encryption.js +0 -1
- package/dist/src/security/file-filter.js +0 -30
- package/dist/src/security/index.js +0 -3
- package/dist/src/security/sanitizer.js +0 -49
- package/dist/src/security/secret-scanner.js +0 -56
- package/dist/src/session/agy/adapter.js +0 -159
- package/dist/src/session/agy/cli.js +0 -87
- package/dist/src/session/agy/hook-installer.js +0 -62
- package/dist/src/session/agy/hook.js +0 -167
- package/dist/src/session/agy/index.js +0 -5
- package/dist/src/session/agy/project-resolver.js +0 -27
- package/dist/src/session/agy/recovery.js +0 -112
- package/dist/src/session/agy/transcript.js +0 -191
- package/dist/src/session/codex/adapter.js +0 -138
- package/dist/src/session/codex/cli.js +0 -236
- package/dist/src/session/codex/context-hook-installer.js +0 -70
- package/dist/src/session/codex/context-hook.js +0 -69
- package/dist/src/session/codex/discovery.js +0 -138
- package/dist/src/session/codex/index.js +0 -6
- package/dist/src/session/codex/notify-installer.js +0 -135
- package/dist/src/session/codex/project-resolver.js +0 -25
- package/dist/src/session/codex/recovery.js +0 -27
- package/dist/src/session/codex/rollout.js +0 -186
- package/dist/src/session/core.js +0 -239
- package/dist/src/session/identity.js +0 -57
- package/dist/src/session/index.js +0 -9
- package/dist/src/session/learner/cli.js +0 -62
- package/dist/src/session/learner/extractor.js +0 -461
- package/dist/src/session/learner/index.js +0 -4
- package/dist/src/session/learner/journal.js +0 -159
- package/dist/src/session/learner/learner.js +0 -124
- package/dist/src/session/learner/types.js +0 -1
- package/dist/src/session/opencode/adapter.js +0 -553
- package/dist/src/session/opencode/cli.js +0 -121
- package/dist/src/session/opencode/index.js +0 -2
- package/dist/src/session/opencode/plugin-installer.js +0 -230
- package/dist/src/session/store.js +0 -242
- package/dist/src/session/types.js +0 -1
- package/dist/src/session/utils.js +0 -47
- package/dist/src/session/wal.js +0 -303
- package/dist/src/snapshot/index.js +0 -2
- package/dist/src/snapshot/manager.js +0 -130
- package/dist/src/snapshot/test-snapshot.js +0 -28
- package/dist/src/snapshot/types.js +0 -1
- package/dist/src/storage/architecture-store.js +0 -37
- package/dist/src/storage/cleanup-health.js +0 -20
- package/dist/src/storage/code-analysis-store.js +0 -35
- package/dist/src/storage/code-chunk-store.js +0 -25
- package/dist/src/storage/code-graph-store.js +0 -24
- package/dist/src/storage/code-manifest-store.js +0 -24
- package/dist/src/storage/code-vector-store.js +0 -25
- package/dist/src/storage/github/client.js +0 -1
- package/dist/src/storage/github/index.js +0 -1
- package/dist/src/storage/google-drive/client.js +0 -1
- package/dist/src/storage/google-drive/index.js +0 -1
- package/dist/src/storage/huggingface/client.js +0 -116
- package/dist/src/storage/huggingface/index.js +0 -1
- package/dist/src/storage/index.js +0 -16
- package/dist/src/storage/list-bucket-raw.js +0 -14
- package/dist/src/storage/list-bucket-tree.js +0 -38
- package/dist/src/storage/local/client.js +0 -99
- package/dist/src/storage/local/index.js +0 -1
- package/dist/src/storage/memory-store.js +0 -30
- package/dist/src/storage/project/cleanup-layout-v1.js +0 -72
- package/dist/src/storage/project/folder.js +0 -15
- package/dist/src/storage/project/index.js +0 -3
- package/dist/src/storage/project/layout.js +0 -74
- package/dist/src/storage/project/migrate-layout-v2.js +0 -101
- package/dist/src/storage/project/migrate.js +0 -73
- package/dist/src/storage/project/scoped-provider.js +0 -165
- package/dist/src/storage/provider.js +0 -26
- package/dist/src/storage/retrying-provider.js +0 -23
- package/dist/src/storage/test-connection.js +0 -32
- package/dist/src/storage/type-resolution-store.js +0 -26
- package/dist/src/storage/types.js +0 -1
- package/dist/src/storage/vector-store.js +0 -30
- package/dist/src/storage/visualization-store.js +0 -25
- package/dist/src/sync/compressor.js +0 -1
- package/dist/src/sync/conflict-resolver.js +0 -1
- package/dist/src/sync/downloader.js +0 -1
- package/dist/src/sync/index.js +0 -1
- package/dist/src/sync/sync-engine.js +0 -1
- package/dist/src/sync/upload-queue.js +0 -1
- package/dist/src/utils/retry.js +0 -29
- package/dist/src/visualization/server.js +0 -270
- package/dist/src/work-continuity/brief-cache.js +0 -107
- package/dist/src/work-continuity/brief.js +0 -349
- package/dist/src/work-continuity/cli.js +0 -96
- package/dist/src/work-continuity/context-cli.js +0 -106
- package/dist/src/work-continuity/context-runtime-cli.js +0 -88
- package/dist/src/work-continuity/extractor.js +0 -339
- package/dist/src/work-continuity/handoff.js +0 -185
- package/dist/src/work-continuity/index.js +0 -14
- package/dist/src/work-continuity/injection.js +0 -84
- package/dist/src/work-continuity/journal.js +0 -49
- package/dist/src/work-continuity/learner.js +0 -127
- package/dist/src/work-continuity/reducer.js +0 -316
- package/dist/src/work-continuity/semantic-extractor.js +0 -360
- package/dist/src/work-continuity/semantic-journal.js +0 -55
- package/dist/src/work-continuity/semantic-learner.js +0 -125
- package/dist/src/work-continuity/semantic-reducer.js +0 -268
- package/dist/src/work-continuity/semantic-types.js +0 -1
- package/dist/src/work-continuity/types.js +0 -1
- package/dist/visualization/public/index.html +0 -2896
- package/dist/visualization/public/vendor/3d-force-graph.min.js +0 -5
package/bin/toolnet-memory
CHANGED
|
@@ -35,8 +35,20 @@ run() {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
case "$COMMAND" in
|
|
38
|
+
setup)
|
|
39
|
+
if [ -f "$ROOT/bundle/setup.js" ]; then
|
|
40
|
+
exec node "$ROOT/bundle/setup.js" "$@"
|
|
41
|
+
elif [ -f "$ROOT/src/production/setup.ts" ]; then
|
|
42
|
+
exec npx --yes tsx "$ROOT/src/production/setup.ts" "$@"
|
|
43
|
+
else
|
|
44
|
+
echo "ToolNet setup module missing."
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
;;
|
|
48
|
+
|
|
49
|
+
|
|
38
50
|
doctor)
|
|
39
|
-
run
|
|
51
|
+
run bundle/doctor.js src/production/doctor.ts
|
|
40
52
|
;;
|
|
41
53
|
|
|
42
54
|
run)
|
|
@@ -44,11 +56,11 @@ case "$COMMAND" in
|
|
|
44
56
|
;;
|
|
45
57
|
|
|
46
58
|
mcp)
|
|
47
|
-
run
|
|
59
|
+
run bundle/mcp.js src/mcp/bootstrap.ts
|
|
48
60
|
;;
|
|
49
61
|
|
|
50
62
|
index)
|
|
51
|
-
run
|
|
63
|
+
run bundle/full-index.js src/production/full-index.ts
|
|
52
64
|
;;
|
|
53
65
|
|
|
54
66
|
index:graph)
|
|
@@ -70,28 +82,28 @@ case "$COMMAND" in
|
|
|
70
82
|
;;
|
|
71
83
|
|
|
72
84
|
snapshot:list)
|
|
73
|
-
run
|
|
85
|
+
run bundle/snapshot.js src/production/snapshot-cli.ts list
|
|
74
86
|
;;
|
|
75
87
|
|
|
76
88
|
snapshot:create)
|
|
77
89
|
shift
|
|
78
|
-
run
|
|
90
|
+
run bundle/snapshot.js src/production/snapshot-cli.ts create "$@"
|
|
79
91
|
;;
|
|
80
92
|
|
|
81
93
|
snapshot:restore)
|
|
82
94
|
shift
|
|
83
|
-
run
|
|
95
|
+
run bundle/snapshot.js src/production/snapshot-cli.ts restore "$@"
|
|
84
96
|
;;
|
|
85
97
|
|
|
86
98
|
recover)
|
|
87
|
-
run
|
|
99
|
+
run bundle/snapshot.js src/production/snapshot-cli.ts recover-latest
|
|
88
100
|
;;
|
|
89
101
|
|
|
90
102
|
session:opencode-sync)
|
|
91
103
|
shift
|
|
92
104
|
|
|
93
|
-
if [ -f "$ROOT/
|
|
94
|
-
exec node "$ROOT/
|
|
105
|
+
if [ -f "$ROOT/bundle/opencode.js" ]; then
|
|
106
|
+
exec node "$ROOT/bundle/opencode.js" sync "$@"
|
|
95
107
|
fi
|
|
96
108
|
|
|
97
109
|
if [ -n "${TSX:-}" ] && [ -x "${TSX:-}" ]; then
|
|
@@ -105,8 +117,8 @@ case "$COMMAND" in
|
|
|
105
117
|
session:opencode-recover)
|
|
106
118
|
shift
|
|
107
119
|
|
|
108
|
-
if [ -f "$ROOT/
|
|
109
|
-
exec node "$ROOT/
|
|
120
|
+
if [ -f "$ROOT/bundle/opencode.js" ]; then
|
|
121
|
+
exec node "$ROOT/bundle/opencode.js" recover "$@"
|
|
110
122
|
fi
|
|
111
123
|
|
|
112
124
|
if [ -n "${TSX:-}" ] && [ -x "${TSX:-}" ]; then
|
|
@@ -120,8 +132,8 @@ case "$COMMAND" in
|
|
|
120
132
|
integrate:opencode)
|
|
121
133
|
shift
|
|
122
134
|
|
|
123
|
-
if [ -f "$ROOT/
|
|
124
|
-
exec node "$ROOT/
|
|
135
|
+
if [ -f "$ROOT/bundle/opencode.js" ]; then
|
|
136
|
+
exec node "$ROOT/bundle/opencode.js" install-plugin "$@"
|
|
125
137
|
fi
|
|
126
138
|
|
|
127
139
|
if [ -n "${TSX:-}" ] && [ -x "${TSX:-}" ]; then
|
|
@@ -149,8 +161,8 @@ case "$COMMAND" in
|
|
|
149
161
|
session:agy-sync)
|
|
150
162
|
shift
|
|
151
163
|
|
|
152
|
-
if [ -f "$ROOT/
|
|
153
|
-
exec node "$ROOT/
|
|
164
|
+
if [ -f "$ROOT/bundle/agy.js" ]; then
|
|
165
|
+
exec node "$ROOT/bundle/agy.js" sync "$@"
|
|
154
166
|
fi
|
|
155
167
|
|
|
156
168
|
exec "$TSX" "$ROOT/src/session/agy/cli.ts" sync "$@"
|
|
@@ -159,8 +171,8 @@ case "$COMMAND" in
|
|
|
159
171
|
session:agy-recover)
|
|
160
172
|
shift
|
|
161
173
|
|
|
162
|
-
if [ -f "$ROOT/
|
|
163
|
-
exec node "$ROOT/
|
|
174
|
+
if [ -f "$ROOT/bundle/agy.js" ]; then
|
|
175
|
+
exec node "$ROOT/bundle/agy.js" recover "$@"
|
|
164
176
|
fi
|
|
165
177
|
|
|
166
178
|
exec "$TSX" "$ROOT/src/session/agy/cli.ts" recover "$@"
|
|
@@ -169,8 +181,8 @@ case "$COMMAND" in
|
|
|
169
181
|
integrate:agy)
|
|
170
182
|
shift
|
|
171
183
|
|
|
172
|
-
if [ -f "$ROOT/
|
|
173
|
-
exec node "$ROOT/
|
|
184
|
+
if [ -f "$ROOT/bundle/agy.js" ]; then
|
|
185
|
+
exec node "$ROOT/bundle/agy.js" install-hooks "$@"
|
|
174
186
|
fi
|
|
175
187
|
|
|
176
188
|
exec "$TSX" "$ROOT/src/session/agy/cli.ts" install-hooks "$@"
|
|
@@ -179,8 +191,8 @@ case "$COMMAND" in
|
|
|
179
191
|
session:codex-notify)
|
|
180
192
|
shift
|
|
181
193
|
|
|
182
|
-
if [ -f "$ROOT/
|
|
183
|
-
exec node "$ROOT/
|
|
194
|
+
if [ -f "$ROOT/bundle/codex.js" ]; then
|
|
195
|
+
exec node "$ROOT/bundle/codex.js" notify "$@"
|
|
184
196
|
fi
|
|
185
197
|
|
|
186
198
|
if [ -x "${TSX:-}" ]; then
|
|
@@ -193,8 +205,8 @@ case "$COMMAND" in
|
|
|
193
205
|
session:codex-sync)
|
|
194
206
|
shift
|
|
195
207
|
|
|
196
|
-
if [ -f "$ROOT/
|
|
197
|
-
exec node "$ROOT/
|
|
208
|
+
if [ -f "$ROOT/bundle/codex.js" ]; then
|
|
209
|
+
exec node "$ROOT/bundle/codex.js" sync "$@"
|
|
198
210
|
fi
|
|
199
211
|
|
|
200
212
|
exec "$TSX" "$ROOT/src/session/codex/cli.ts" sync "$@"
|
|
@@ -203,8 +215,8 @@ case "$COMMAND" in
|
|
|
203
215
|
session:codex-recover)
|
|
204
216
|
shift
|
|
205
217
|
|
|
206
|
-
if [ -f "$ROOT/
|
|
207
|
-
exec node "$ROOT/
|
|
218
|
+
if [ -f "$ROOT/bundle/codex.js" ]; then
|
|
219
|
+
exec node "$ROOT/bundle/codex.js" recover "$@"
|
|
208
220
|
fi
|
|
209
221
|
|
|
210
222
|
exec "$TSX" "$ROOT/src/session/codex/cli.ts" recover "$@"
|
|
@@ -213,8 +225,8 @@ case "$COMMAND" in
|
|
|
213
225
|
integrate:codex)
|
|
214
226
|
shift
|
|
215
227
|
|
|
216
|
-
if [ -f "$ROOT/
|
|
217
|
-
exec node "$ROOT/
|
|
228
|
+
if [ -f "$ROOT/bundle/codex.js" ]; then
|
|
229
|
+
exec node "$ROOT/bundle/codex.js" install-notify "$@"
|
|
218
230
|
fi
|
|
219
231
|
|
|
220
232
|
exec "$TSX" "$ROOT/src/session/codex/cli.ts" install-notify "$@"
|
|
@@ -223,8 +235,8 @@ case "$COMMAND" in
|
|
|
223
235
|
memory:reconcile)
|
|
224
236
|
shift
|
|
225
237
|
|
|
226
|
-
if [ -f "$ROOT/
|
|
227
|
-
exec node "$ROOT/
|
|
238
|
+
if [ -f "$ROOT/bundle/learner.js" ]; then
|
|
239
|
+
exec node "$ROOT/bundle/learner.js" reconcile "$@"
|
|
228
240
|
fi
|
|
229
241
|
|
|
230
242
|
if [ -x "${TSX:-}" ]; then
|
|
@@ -238,8 +250,8 @@ case "$COMMAND" in
|
|
|
238
250
|
project:manual-init)
|
|
239
251
|
shift
|
|
240
252
|
|
|
241
|
-
if [ -f "$ROOT/
|
|
242
|
-
exec node "$ROOT/
|
|
253
|
+
if [ -f "$ROOT/bundle/project-manual.js" ]; then
|
|
254
|
+
exec node "$ROOT/bundle/project-manual.js" init "$@"
|
|
243
255
|
fi
|
|
244
256
|
|
|
245
257
|
exec "$TSX" "$ROOT/src/project-manual/cli.ts" init "$@"
|
|
@@ -248,8 +260,8 @@ case "$COMMAND" in
|
|
|
248
260
|
project:manual-show)
|
|
249
261
|
shift
|
|
250
262
|
|
|
251
|
-
if [ -f "$ROOT/
|
|
252
|
-
exec node "$ROOT/
|
|
263
|
+
if [ -f "$ROOT/bundle/project-manual.js" ]; then
|
|
264
|
+
exec node "$ROOT/bundle/project-manual.js" show "$@"
|
|
253
265
|
fi
|
|
254
266
|
|
|
255
267
|
exec "$TSX" "$ROOT/src/project-manual/cli.ts" show "$@"
|
|
@@ -258,8 +270,8 @@ case "$COMMAND" in
|
|
|
258
270
|
project:manual-sync)
|
|
259
271
|
shift
|
|
260
272
|
|
|
261
|
-
if [ -f "$ROOT/
|
|
262
|
-
exec node "$ROOT/
|
|
273
|
+
if [ -f "$ROOT/bundle/project-manual.js" ]; then
|
|
274
|
+
exec node "$ROOT/bundle/project-manual.js" sync "$@"
|
|
263
275
|
fi
|
|
264
276
|
|
|
265
277
|
exec "$TSX" "$ROOT/src/project-manual/cli.ts" sync "$@"
|
|
@@ -268,8 +280,8 @@ case "$COMMAND" in
|
|
|
268
280
|
work:status)
|
|
269
281
|
shift
|
|
270
282
|
|
|
271
|
-
if [ -f "$ROOT/
|
|
272
|
-
exec node "$ROOT/
|
|
283
|
+
if [ -f "$ROOT/bundle/work-continuity.js" ]; then
|
|
284
|
+
exec node "$ROOT/bundle/work-continuity.js" status "$@"
|
|
273
285
|
fi
|
|
274
286
|
|
|
275
287
|
exec "$TSX" "$ROOT/src/work-continuity/cli.ts" status "$@"
|
|
@@ -278,8 +290,8 @@ case "$COMMAND" in
|
|
|
278
290
|
work:json)
|
|
279
291
|
shift
|
|
280
292
|
|
|
281
|
-
if [ -f "$ROOT/
|
|
282
|
-
exec node "$ROOT/
|
|
293
|
+
if [ -f "$ROOT/bundle/work-continuity.js" ]; then
|
|
294
|
+
exec node "$ROOT/bundle/work-continuity.js" json "$@"
|
|
283
295
|
fi
|
|
284
296
|
|
|
285
297
|
exec "$TSX" "$ROOT/src/work-continuity/cli.ts" json "$@"
|
|
@@ -288,8 +300,8 @@ case "$COMMAND" in
|
|
|
288
300
|
work:reconcile)
|
|
289
301
|
shift
|
|
290
302
|
|
|
291
|
-
if [ -f "$ROOT/
|
|
292
|
-
exec node "$ROOT/
|
|
303
|
+
if [ -f "$ROOT/bundle/work-continuity.js" ]; then
|
|
304
|
+
exec node "$ROOT/bundle/work-continuity.js" reconcile "$@"
|
|
293
305
|
fi
|
|
294
306
|
|
|
295
307
|
exec "$TSX" "$ROOT/src/work-continuity/cli.ts" reconcile "$@"
|
|
@@ -298,8 +310,8 @@ case "$COMMAND" in
|
|
|
298
310
|
brief)
|
|
299
311
|
shift
|
|
300
312
|
|
|
301
|
-
if [ -f "$ROOT/
|
|
302
|
-
exec node "$ROOT/
|
|
313
|
+
if [ -f "$ROOT/bundle/context.js" ]; then
|
|
314
|
+
exec node "$ROOT/bundle/context.js" brief "$@"
|
|
303
315
|
fi
|
|
304
316
|
|
|
305
317
|
exec "$TSX" "$ROOT/src/work-continuity/context-cli.ts" brief "$@"
|
|
@@ -308,8 +320,8 @@ case "$COMMAND" in
|
|
|
308
320
|
brief:json)
|
|
309
321
|
shift
|
|
310
322
|
|
|
311
|
-
if [ -f "$ROOT/
|
|
312
|
-
exec node "$ROOT/
|
|
323
|
+
if [ -f "$ROOT/bundle/context.js" ]; then
|
|
324
|
+
exec node "$ROOT/bundle/context.js" brief-json "$@"
|
|
313
325
|
fi
|
|
314
326
|
|
|
315
327
|
exec "$TSX" "$ROOT/src/work-continuity/context-cli.ts" brief-json "$@"
|
|
@@ -318,8 +330,8 @@ case "$COMMAND" in
|
|
|
318
330
|
handoff:latest)
|
|
319
331
|
shift
|
|
320
332
|
|
|
321
|
-
if [ -f "$ROOT/
|
|
322
|
-
exec node "$ROOT/
|
|
333
|
+
if [ -f "$ROOT/bundle/context.js" ]; then
|
|
334
|
+
exec node "$ROOT/bundle/context.js" handoff-latest "$@"
|
|
323
335
|
fi
|
|
324
336
|
|
|
325
337
|
exec "$TSX" "$ROOT/src/work-continuity/context-cli.ts" handoff-latest "$@"
|
|
@@ -328,8 +340,8 @@ case "$COMMAND" in
|
|
|
328
340
|
context:sync)
|
|
329
341
|
shift
|
|
330
342
|
|
|
331
|
-
if [ -f "$ROOT/
|
|
332
|
-
exec node "$ROOT/
|
|
343
|
+
if [ -f "$ROOT/bundle/context-runtime.js" ]; then
|
|
344
|
+
exec node "$ROOT/bundle/context-runtime.js" sync "$@"
|
|
333
345
|
fi
|
|
334
346
|
|
|
335
347
|
exec "$TSX" "$ROOT/src/work-continuity/context-runtime-cli.ts" sync "$@"
|
|
@@ -338,8 +350,8 @@ case "$COMMAND" in
|
|
|
338
350
|
context:print)
|
|
339
351
|
shift
|
|
340
352
|
|
|
341
|
-
if [ -f "$ROOT/
|
|
342
|
-
exec node "$ROOT/
|
|
353
|
+
if [ -f "$ROOT/bundle/context-runtime.js" ]; then
|
|
354
|
+
exec node "$ROOT/bundle/context-runtime.js" print "$@"
|
|
343
355
|
fi
|
|
344
356
|
|
|
345
357
|
exec "$TSX" "$ROOT/src/work-continuity/context-runtime-cli.ts" print "$@"
|
|
@@ -348,8 +360,8 @@ case "$COMMAND" in
|
|
|
348
360
|
context:refresh)
|
|
349
361
|
shift
|
|
350
362
|
|
|
351
|
-
if [ -f "$ROOT/
|
|
352
|
-
exec node "$ROOT/
|
|
363
|
+
if [ -f "$ROOT/bundle/context-runtime.js" ]; then
|
|
364
|
+
exec node "$ROOT/bundle/context-runtime.js" refresh "$@"
|
|
353
365
|
fi
|
|
354
366
|
|
|
355
367
|
exec "$TSX" "$ROOT/src/work-continuity/context-runtime-cli.ts" refresh "$@"
|
|
@@ -375,6 +387,7 @@ ToolNet Memory
|
|
|
375
387
|
|
|
376
388
|
Commands:
|
|
377
389
|
toolnet-memory doctor
|
|
390
|
+
toolnet-memory setup
|
|
378
391
|
toolnet-memory index
|
|
379
392
|
toolnet-memory index:graph
|
|
380
393
|
toolnet-memory incremental
|
package/bundle/agy.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import{existsSync as St,readFileSync as vt}from"node:fs";import{homedir as bt}from"node:os";import{join as wt}from"node:path";function jt(t){let e=t.trim();return e.length>=2&&e.startsWith('"')&&e.endsWith('"')?(e=e.slice(1,-1),e.replace(/\\n/g,`
|
|
2
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")):e.length>=2&&e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e}function kt(){let t=process.env.TOOLNET_GLOBAL_ENV??wt(bt(),".config","toolnet-memory",".env");if(!St(t))return;let e=vt(t,"utf8");for(let n of e.split(/\r?\n/)){let r=n.trim();if(!r||r.startsWith("#"))continue;r.startsWith("export ")&&(r=r.slice(7));let s=r.indexOf("=");if(s<=0)continue;let o=r.slice(0,s).trim();/^[A-Za-z_][A-Za-z0-9_]*$/.test(o)&&process.env[o]===void 0&&(process.env[o]=jt(r.slice(s+1)))}}kt();function F(t,e){return t===void 0?e:["1","true","yes","on"].includes(t.toLowerCase())}function L(t,e){if(!t)return e;let n=Number(t);return Number.isFinite(n)?n:e}function ve(){return{memory:{autoCapture:F(process.env.MEMORY_AUTO_CAPTURE,!0),autoRetrieve:F(process.env.MEMORY_AUTO_RETRIEVE,!0),autoSummarize:F(process.env.MEMORY_AUTO_SUMMARIZE,!0),autoSync:F(process.env.MEMORY_AUTO_SYNC,!0)},retrieval:{maxCandidates:L(process.env.MEMORY_MAX_CANDIDATES,50),rerankTop:L(process.env.MEMORY_RERANK_TOP,10),finalContext:L(process.env.MEMORY_FINAL_CONTEXT,5),tokenBudget:L(process.env.MEMORY_TOKEN_BUDGET,2e3)},storage:{provider:process.env.MEMORY_STORAGE_PROVIDER??"huggingface",huggingface:{namespace:process.env.HF_NAMESPACE,bucket:process.env.HF_BUCKET,accessKeyId:process.env.HF_S3_ACCESS_KEY_ID,secretAccessKey:process.env.HF_S3_SECRET_ACCESS_KEY},localRoot:process.env.MEMORY_LOCAL_STORAGE_PATH},cache:{maxMb:L(process.env.MEMORY_LOCAL_CACHE_MB,200)}}}import{createHash as xt}from"node:crypto";import{existsSync as je,mkdirSync as It,readFileSync as Pt,renameSync as Ot,writeFileSync as At}from"node:fs";import{basename as Et,dirname as K,join as ae,parse as ke,resolve as q}from"node:path";var xe=".toolnet",Mt="project.json";function Rt(t){return xt("sha256").update(t).digest("hex").slice(0,16)}function ce(t){return ae(t,xe,Mt)}function Nt(t){return je(ce(t))}function Tt(t){let e=q(t),n=ke(e).root;for(;;){if(Nt(e))return e;if(e===n)break;let r=K(e);if(r===e)break;e=r}return null}function Ct(t){let e=q(t),n=ke(e).root,r=[".git","package.json","pyproject.toml","Cargo.toml","go.mod","composer.json"];for(;;){if(r.some(o=>je(ae(e,o))))return e;if(e===n)break;let s=K(e);if(s===e)break;e=s}return q(t)}function _t(t){let e;try{e=JSON.parse(Pt(t,"utf8"))}catch(s){throw new Error(`Invalid ToolNet project manifest: ${t}: ${s instanceof Error?s.message:String(s)}`)}if(!e||typeof e!="object")throw new Error(`Invalid ToolNet project manifest: ${t}`);let n=e;if(typeof n.id!="string"||!n.id.trim())throw new Error(`ToolNet project manifest is missing id: ${t}`);if(typeof n.name!="string"||!n.name.trim())throw new Error(`ToolNet project manifest is missing name: ${t}`);let r=new Date().toISOString();return{version:1,id:n.id,name:n.name,remote:typeof n.remote=="string"&&n.remote.trim()?n.remote:n.name,rootPath:typeof n.rootPath=="string"?n.rootPath:K(K(t)),createdAt:typeof n.createdAt=="string"?n.createdAt:r,updatedAt:typeof n.updatedAt=="string"?n.updatedAt:r,graphVersion:typeof n.graphVersion=="number"?n.graphVersion:0,memoryVersion:typeof n.memoryVersion=="number"?n.memoryVersion:0,metadata:n.metadata&&typeof n.metadata=="object"?n.metadata:void 0}}function be(t,e){let n=ae(t,xe);It(n,{recursive:!0});let r=ce(t),s=`${r}.tmp-${process.pid}`;At(s,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,{encoding:"utf8",mode:384}),Ot(s,r)}function we(t,e){return{id:t.id,name:t.name,remote:t.remote,rootPath:e,createdAt:t.createdAt,updatedAt:t.updatedAt,graphVersion:t.graphVersion,memoryVersion:t.memoryVersion,metadata:t.metadata}}var D=class{detect(e=process.cwd()){let n=q(e),r=Tt(n);if(r){let u=ce(r),a=_t(u);return a.rootPath!==r&&(a.rootPath=r,a.updatedAt=new Date().toISOString(),be(r,a)),we(a,r)}let s=Ct(n),o=new Date().toISOString(),i=Et(s),c={version:1,id:Rt(s),name:i,remote:i,rootPath:s,createdAt:o,updatedAt:o,graphVersion:0,memoryVersion:0};return be(s,c),we(c,s)}};var $t=[{type:"openai_key",regex:/\bsk-[A-Za-z0-9_\-]{20,}\b/g},{type:"huggingface_token",regex:/\bhf_[A-Za-z0-9]{20,}\b/g},{type:"hf_s3_access_key",regex:/\bHFAK[A-Za-z0-9]{8,}\b/g},{type:"bearer_token",regex:/\bBearer\s+[A-Za-z0-9._\-]{16,}\b/gi},{type:"jwt",regex:/\beyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\b/g},{type:"private_key",regex:/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g},{type:"password_assignment",regex:/\b(password|passwd|pwd)\s*[:=]\s*["']?[^"'\s]{6,}["']?/gi},{type:"secret_assignment",regex:/\b(secret|api[_-]?key|access[_-]?token|refresh[_-]?token)\s*[:=]\s*["']?[^"'\s]{8,}["']?/gi},{type:"cookie",regex:/\b(cookie|set-cookie)\s*[:=]\s*[^;\n]{8,}/gi}],B=class{scan(e){let n=[];for(let r of $t){let s=new RegExp(r.regex.source,r.regex.flags);for(let o of e.matchAll(s))n.push({type:r.type,value:o[0]})}return n}hasSecrets(e){return this.scan(e).length>0}};var z=class{scanner=new B;sanitize(e){let n=e,r=this.scanner.scan(e),s=new Set;for(let o of r)s.add(o.type),n=n.split(o.value).join(`[REDACTED:${o.type}]`);return{text:n,redacted:r.length,secretTypes:[...s]}}sanitizeValue(e){if(typeof e=="string")return this.sanitize(e).text;if(Array.isArray(e))return e.map(n=>this.sanitizeValue(n));if(e&&typeof e=="object"){let n={};for(let[r,s]of Object.entries(e)){let o=r.toLowerCase();o.includes("password")||o.includes("secret")||o.includes("token")||o.includes("cookie")||o.includes("authorization")?n[r]="[REDACTED]":n[r]=this.sanitizeValue(s)}return n}return e}};import{homedir as Zt}from"node:os";import{join as Qt}from"node:path";import{DeleteObjectCommand as Lt,GetObjectCommand as zt,HeadObjectCommand as Wt,ListObjectsV2Command as Ft,PutObjectCommand as Kt,S3Client as qt}from"@aws-sdk/client-s3";import{getSignedUrl as Dt}from"@aws-sdk/s3-request-presigner";var J=class{name="huggingface";client;bucket;constructor(e){this.bucket=e.bucket,this.client=new qt({region:"us-east-1",endpoint:`https://s3.hf.co/${e.namespace}`,forcePathStyle:!0,requestChecksumCalculation:"WHEN_REQUIRED",responseChecksumValidation:"WHEN_REQUIRED",credentials:{accessKeyId:e.accessKeyId,secretAccessKey:e.secretAccessKey}})}async put(e,n,r="application/octet-stream"){let s=typeof n=="string"?Buffer.from(n,"utf8"):n;await this.client.send(new Kt({Bucket:this.bucket,Key:e,Body:s,ContentType:r}))}async get(e){let n=await Dt(this.client,new zt({Bucket:this.bucket,Key:e}),{expiresIn:60}),r=await fetch(n,{redirect:"follow"});if(r.status===404)return null;if(!r.ok)throw new Error(`HF download failed: ${r.status} ${r.statusText}`);return new Uint8Array(await r.arrayBuffer())}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await this.client.send(new Wt({Bucket:this.bucket,Key:e})),!0}catch(n){if(typeof n=="object"&&n!==null&&"$metadata"in n&&n.$metadata?.httpStatusCode===404)return!1;throw n}}async delete(e){await this.client.send(new Lt({Bucket:this.bucket,Key:e}))}async list(e=""){let n=[],r;do{let s=await this.client.send(new Ft({Bucket:this.bucket,Prefix:e||void 0,ContinuationToken:r}));for(let o of s.Contents??[])o.Key&&n.push({key:o.Key,size:o.Size,updatedAt:o.LastModified?.toISOString()});r=s.IsTruncated?s.NextContinuationToken:void 0}while(r);return n}};import{access as Ie,mkdir as Bt,readFile as Jt,readdir as Vt,rm as Ut,stat as Pe,writeFile as Ht}from"node:fs/promises";import{dirname as Yt,join as Gt,relative as Oe,resolve as Xt}from"node:path";var W=class{constructor(e){this.root=e}root;name="local";path(e){let n=e.replace(/^\/+/,"");return Xt(this.root,n)}async put(e,n){let r=this.path(e);await Bt(Yt(r),{recursive:!0}),await Ht(r,n)}async get(e){try{return await Jt(this.path(e))}catch(n){if(typeof n=="object"&&n!==null&&"code"in n&&n.code==="ENOENT")return null;throw n}}async getText(e){let n=await this.get(e);return n?Buffer.from(n).toString("utf8"):null}async exists(e){try{return await Ie(this.path(e)),!0}catch{return!1}}async delete(e){await Ut(this.path(e),{force:!0})}async list(e=""){let n=this.path(e),r=[];try{await Ie(n)}catch{return r}let s=async i=>{let c=await Vt(i,{withFileTypes:!0});for(let u of c){let a=Gt(i,u.name);if(u.isDirectory()){await s(a);continue}let m=await Pe(a);r.push({key:Oe(this.root,a),size:m.size,updatedAt:m.mtime.toISOString()})}},o=await Pe(n);return o.isDirectory()?await s(n):r.push({key:Oe(this.root,n),size:o.size,updatedAt:o.mtime.toISOString()}),r}};function Ae(t){let e=t.localRoot??Qt(Zt(),".toolnet-memory","storage");if(t.provider==="huggingface"){let n=t.huggingface;return n?.namespace&&n.bucket&&n.accessKeyId&&n.secretAccessKey?new J({namespace:n.namespace,bucket:n.bucket,accessKeyId:n.accessKeyId,secretAccessKey:n.secretAccessKey}):(console.warn("[storage] Hugging Face credentials missing. Using local fallback."),new W(e))}return new W(e)}function en(t){return new Promise(e=>setTimeout(e,t))}async function Ee(t,e={}){let n=Math.max(1,e.attempts??3),r=e.baseDelayMs??150,s=e.maxDelayMs??2e3,o;for(let i=1;i<=n;i++)try{return await t()}catch(c){if(o=c,i>=n)break;let u=Math.min(s,r*2**(i-1)),a=Math.floor(Math.random()*Math.max(1,u*.2));await en(u+a)}throw o}var tn=new Set(["put","get","getText","delete","list"]);function Me(t,e={}){return new Proxy(t,{get(n,r){let s=Reflect.get(n,r,n);return typeof s!="function"?s:tn.has(r)?(...o)=>Ee(()=>Promise.resolve(s.apply(n,o)),e):s.bind(n)}})}function Re(t){let e=t.trim().replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,"").slice(0,100);if(!e||e==="."||e==="..")throw new Error("Invalid project storage folder");return e}function Ne(t){let e=t.replace(/^\/+/,"");if(e.startsWith("memories/"))return"memory/records/"+e.slice(9);if(e.startsWith("vectors/"))return"memory/vectors/"+e.slice(8);if(e.startsWith("graph/"))return"code/graph/"+e.slice(6);let n=e.match(/^(snapshots\/[^/]+\/)memories\/(.+)$/);if(n)return`${n[1]}memory/records/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)vectors\/(.+)$/),n)return`${n[1]}memory/vectors/${n[2]}`;if(n=e.match(/^(snapshots\/[^/]+\/)graph\/(.+)$/),n)return`${n[1]}code/graph/${n[2]}`;let r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)memories\/(.+)$/);if(r)return`${r[1]}memory/records/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)vectors\/(.+)$/),r)return`${r[1]}memory/vectors/${r[2]}`;if(r=e.match(/^(projects\/[^/]+\/snapshots\/[^/]+\/)graph\/(.+)$/),r)return`${r[1]}code/graph/${r[2]}`;let s=e.match(/^(projects\/[^/]+\/)memories\/(.+)$/);return s?`${s[1]}memory/records/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)vectors\/(.+)$/),s?`${s[1]}memory/vectors/${s[2]}`:(s=e.match(/^(projects\/[^/]+\/)graph\/(.+)$/),s?`${s[1]}code/graph/${s[2]}`:e))}var V=class{constructor(e,n,r,s){this.provider=e;this.name=e.name,this.projectId=n,this.projectName=r,this.folder=Re(s??r),this.sourcePrefix=`projects/${n}`,this.targetPrefix=`projects/${this.folder}`}provider;name;folder;sourcePrefix;targetPrefix;projectId;projectName;registryPromise;async registerProject(){let e=`${this.targetPrefix}/project.json`,n=new Date().toISOString(),r=n,s=await this.provider.getText(e);if(s){let i;try{i=JSON.parse(s)}catch(c){throw new Error(`Invalid remote ToolNet project manifest at ${e}: ${c instanceof Error?c.message:String(c)}`)}if(typeof i.id=="string"&&i.id!==this.projectId)throw new Error(["ToolNet remote project namespace collision.",`Remote folder: ${this.targetPrefix}`,`Existing project id: ${i.id}`,`Current project id: ${this.projectId}`,"Refusing to mix data from two projects."].join(" "));typeof i.createdAt=="string"&&(r=i.createdAt)}let o={version:1,id:this.projectId,name:this.projectName,remote:this.folder,createdAt:r,updatedAt:n};await this.provider.put(e,JSON.stringify(o,null,2)+`
|
|
4
|
+
`,"application/json")}async ensureRegistered(){return this.registryPromise||(this.registryPromise=this.registerProject()),this.registryPromise}key(e){if(e=Ne(e),e===this.sourcePrefix)return this.targetPrefix;if(e.startsWith(`${this.sourcePrefix}/`))return this.targetPrefix+e.slice(this.sourcePrefix.length);if(e===this.targetPrefix||e.startsWith(`${this.targetPrefix}/`))return e;if(e.startsWith("projects/"))throw new Error(["Cross-project storage access denied.",`Current project: ${this.targetPrefix}`,`Requested key: ${e}`].join(" "));return e}async put(e,n,r){return await this.ensureRegistered(),this.provider.put(this.key(e),n,r)}async get(e){return await this.ensureRegistered(),this.provider.get(this.key(e))}async getText(e){return await this.ensureRegistered(),this.provider.getText(this.key(e))}async delete(e){return await this.ensureRegistered(),this.provider.delete(this.key(e))}async exists(e){return await this.ensureRegistered(),this.provider.exists(this.key(e))}async list(e){return await this.ensureRegistered(),this.provider.list(this.key(e))}};import{homedir as ye}from"node:os";import{join as lt,resolve as Rr}from"node:path";import{join as un}from"node:path";import{createHash as nn}from"node:crypto";import{dirname as rn}from"node:path";import{mkdirSync as sn,readFileSync as on,renameSync as an,writeFileSync as cn}from"node:fs";function v(t){return nn("sha256").update(t).digest("hex")}function ue(t){if(Array.isArray(t))return t.map(ue);if(t&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=ue(e[r]);return n}return t}function Te(t){return JSON.stringify(ue(t))}function Ce(t){try{return JSON.parse(on(t,"utf8"))}catch{return null}}function O(t,e){sn(rn(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;cn(n,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{encoding:"utf8",mode:384}),an(n,t)}function _e(t,e){let n=t.trim(),r=n.replace(/\s+/g,"_").replace(/[^A-Za-z0-9._-]/g,"_").replace(/_+/g,"_").replace(/^\.+|\.+$/g,""),s=v(n).slice(0,12);if(!r||r==="."||r==="..")return`${e}--${s}`;let o=r.slice(0,100);return o===n&&n.length<=100?o:`${o.slice(0,85)}--${s}`}function $e(t,e,n){let r=e.trim(),s=n.trim();if(!r)throw new Error("Session agent is required");if(!s)throw new Error("Native session ID is required");let o=_e(r.toLowerCase(),"agent"),i=_e(s,"session");return{projectId:t.id,projectName:t.name,projectRoot:t.rootPath,agent:r,nativeSessionId:s,sessionKey:`${r}:${s}`,remotePrefix:["projects",t.id,"sessions",o,i].join("/"),localDirectory:un(t.rootPath,".toolnet","sessions",o,i)}}function Le(t){return String(t).padStart(12,"0")}var U=class{constructor(e,n=100,r=512*1024){this.storage=e;this.maxEventsPerChunk=n;this.maxChunkBytes=r;if(n<1)throw new Error("maxEventsPerChunk must be positive");if(r<1024)throw new Error("maxChunkBytes is too small")}storage;maxEventsPerChunk;maxChunkBytes;async getJson(e){let n=await this.storage.getText(e);return n?JSON.parse(n):null}async putJson(e,n){await this.storage.put(e,JSON.stringify(n,null,2)+`
|
|
6
|
+
`,"application/json")}async scan(e){let n=`${e.remotePrefix}/events/`,r=await this.storage.list(n),s=[],o=0;for(let i of r){let c=i.key.match(/\/events\/(\d+)-(\d+)-[a-f0-9]+\.jsonl$/);if(!c)continue;let u=Number(c[1]),a=Number(c[2]);!Number.isFinite(u)||!Number.isFinite(a)||(s.push({key:i.key,start:u,end:a}),o=Math.max(o,a))}return s.sort((i,c)=>i.start-c.start),{chunks:s,maxSequence:o}}split(e){let n=[],r=[],s=0;for(let o of e){let i=Buffer.byteLength(JSON.stringify(o)+`
|
|
7
|
+
`,"utf8");r.length>0&&(r.length>=this.maxEventsPerChunk||s+i>this.maxChunkBytes)&&(n.push(r),r=[],s=0),r.push(o),s+=i}return r.length>0&&n.push(r),n}async loadManifest(e){return this.getJson(`${e.remotePrefix}/session.json`)}async loadCursor(e){return this.getJson(`${e.remotePrefix}/cursor.json`)}async recover(e){let n=await this.scan(e);return{maxSequence:n.maxSequence,chunkCount:n.chunks.length}}async append(e,n,r,s={}){let o=await this.loadManifest(e),i=await this.scan(e),c=n.filter(d=>d.sequence>i.maxSequence),u=0;for(let d of this.split(c)){let y=d[0],b=d[d.length-1],M=d.map(R=>JSON.stringify(R)).join(`
|
|
8
|
+
`)+`
|
|
9
|
+
`,N=v(M).slice(0,16),P=[e.remotePrefix,"events",`${Le(y.sequence)}-${Le(b.sequence)}-${N}.jsonl`].join("/");await this.storage.exists(P)||await this.storage.put(P,M,"application/x-ndjson"),u+=d.length}let a=await this.scan(e),m=n[n.length-1],l=o?.status??"active";m?.type==="session_end"||m?.type==="session_idle"?l="idle":m?.type==="error"?l="error":n.length>0&&(l="active");let f=new Date().toISOString(),h=n[0],S={version:1,projectId:e.projectId,projectName:e.projectName,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,status:l,createdAt:o?.createdAt??h?.timestamp??f,updatedAt:m?.timestamp??f,firstEventAt:o?.firstEventAt??h?.timestamp,lastEventAt:m?.timestamp??o?.lastEventAt,eventCount:a.maxSequence,chunkCount:a.chunks.length,metadata:{...o?.metadata,...s.metadata}};(s.title??o?.title)&&(S.title=s.title??o?.title);let g={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,lastLocalSequence:n.length>0?n[n.length-1].sequence:a.maxSequence,lastRemoteSequence:a.maxSequence,sourceCursors:r,updatedAt:f};return await this.putJson(`${e.remotePrefix}/cursor.json`,g),await this.putJson(`${e.remotePrefix}/session.json`,S),{uploadedEvents:u,lastRemoteSequence:a.maxSequence,eventCount:S.eventCount,chunkCount:S.chunkCount,status:l}}};import{closeSync as pe,existsSync as pn,fsyncSync as ln,mkdirSync as dn,openSync as le,readSync as mn,rmSync as ze,statSync as We,writeSync as fn}from"node:fs";import{join as de}from"node:path";var gn=12e4,yn=80,hn=2e3;function Sn(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var H=class{constructor(e){this.identity=e;dn(e.localDirectory,{recursive:!0}),this.eventsFile=de(e.localDirectory,"events.jsonl"),this.stateFile=de(e.localDirectory,"state.json"),this.lockFile=de(e.localDirectory,"journal.lock")}identity;eventsFile;stateFile;lockFile;initialState(){let e=new Date().toISOString();return{version:1,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,status:"idle",createdAt:e,updatedAt:e,lastSequence:0,lastRemoteSequence:0,remoteByteOffset:0,sourceCursors:{},recentEventIds:[]}}loadStateUnsafe(){return Ce(this.stateFile)??this.initialState()}loadState(){return this.withLock(()=>this.loadStateUnsafe())}saveStateUnsafe(e){O(this.stateFile,e)}acquireLock(){for(let e=0;e<yn;e+=1)try{return le(this.lockFile,"wx",384)}catch(n){if(n.code!=="EEXIST")throw n;try{if(Date.now()-We(this.lockFile).mtimeMs>gn){ze(this.lockFile,{force:!0});continue}}catch{}Sn(25)}throw new Error(`Session journal is locked: ${this.lockFile}`)}withLock(e){let n=this.acquireLock();try{return e()}finally{pe(n),ze(this.lockFile,{force:!0})}}append(e){return e.length===0?[]:this.withLock(()=>{let n=this.loadStateUnsafe(),r=new Set(n.recentEventIds),s=n.lastSequence,o=[];for(let l of e){let f=l.timestamp??new Date().toISOString(),h=l.data??{},S=l.provenance?.rawDigest??v(Te(h)),g=l.sourceEventId?[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,l.sourceEventId].join("|"):[this.identity.projectId,this.identity.agent,this.identity.nativeSessionId,s+1,l.type,f,S].join("|"),d=v(g).slice(0,32);if(r.has(d))continue;s+=1;let y={version:1,id:d,sequence:s,projectId:this.identity.projectId,agent:this.identity.agent,nativeSessionId:this.identity.nativeSessionId,type:l.type,timestamp:f,data:h,provenance:{...l.provenance,rawDigest:S}};l.role!==void 0&&(y.role=l.role),l.sourceEventId!==void 0&&(y.sourceEventId=l.sourceEventId),l.sourceSequence!==void 0&&(y.sourceSequence=l.sourceSequence),o.push(y),r.add(d)}if(o.length===0)return[];let i=o.map(l=>JSON.stringify(l)).join(`
|
|
10
|
+
`)+`
|
|
11
|
+
`,c=le(this.eventsFile,"a",384);try{fn(c,i,null,"utf8"),ln(c)}finally{pe(c)}let u=o[o.length-1],a="active";u.type==="session_end"||u.type==="session_idle"?a="idle":u.type==="error"&&(a="error");let m=Array.from(r).slice(-hn);return this.saveStateUnsafe({...n,status:a,updatedAt:u.timestamp,lastSequence:u.sequence,recentEventIds:m}),o})}readPending(){return this.withLock(()=>{let e=this.loadStateUnsafe();if(!pn(this.eventsFile))return{events:[],startOffset:e.remoteByteOffset,endOffset:e.remoteByteOffset};let n=We(this.eventsFile).size,r=Math.min(e.remoteByteOffset,n);if(n<=r)return{events:[],startOffset:r,endOffset:n};let s=n-r,o=Buffer.alloc(s),i=le(this.eventsFile,"r");try{mn(i,o,0,s,r)}finally{pe(i)}return{events:o.toString("utf8").split(`
|
|
12
|
+
`).filter(Boolean).map(a=>JSON.parse(a)),startOffset:r,endOffset:n}})}markRemote(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,lastRemoteSequence:Math.max(r.lastRemoteSequence,e),remoteByteOffset:Math.max(r.remoteByteOffset,n),updatedAt:new Date().toISOString()})})}setSourceCursor(e,n){this.withLock(()=>{let r=this.loadStateUnsafe();this.saveStateUnsafe({...r,sourceCursors:{...r.sourceCursors,[e]:String(n)},updatedAt:new Date().toISOString()})})}};import{closeSync as Cn,existsSync as _n,openSync as $n,readSync as Ln,statSync as zn}from"node:fs";function Fe(t,e){let n=e.toLowerCase();return n.includes("kh\xF4ng \u0111\u01B0\u1EE3c")||n.includes("tuy\u1EC7t \u0111\u1ED1i")||n.includes("must not")||n.includes("never ")?"critical":t==="rule"||t==="decision"?"high":t==="todo"||n.includes("error")||n.includes("failed")||n.includes("exception")?"normal":"temporary"}var Be=[/không được/iu,/tuyệt đối/iu,/bắt buộc/iu,/đừng\s+/iu,/must not/iu,/do not/iu,/don't/iu,/\bnever\b/iu],vn=[/từ giờ/iu,/về sau/iu,/mỗi lần/iu,/luôn luôn/iu,/\bluôn\b/iu,/quy tắc/iu,/workflow/iu,/\balways\b/iu,/\brequired\b/iu,/\bmust\b/iu,/from now on/iu],bn=[/\bchốt\b/iu,/quyết định/iu,/sẽ dùng/iu,/chọn .+ thay/iu,/đổi sang/iu,/chuyển sang/iu,/\bdecided\b/iu,/\bchosen\b/iu,/we will use/iu,/use .+ instead/iu,/switch(?:ed)? to/iu],wn=[/\btodo\b/iu,/cần làm/iu,/cần thêm/iu,/cần sửa/iu,/cần kiểm tra/iu,/tiếp theo/iu,/bước tiếp theo/iu,/còn phải/iu,/còn cần/iu,/next step/iu,/\bneed to\b/iu,/\bremaining\b/iu,/follow[- ]?up/iu],jn=[/đã sửa/iu,/đã fix/iu,/đã khắc phục/iu,/đã xử lý/iu,/hoàn tất/iu,/hoàn thành/iu,/\bfixed\b/iu,/\bresolved\b/iu,/\bimplemented\b/iu,/\bcompleted\b/iu,/\bpasses?\b/iu],Ke=[/kiến trúc/iu,/pipeline/iu,/adapter/iu,/schema/iu,/runtime/iu,/namespace/iu,/storage/iu,/lưu trữ/iu,/workflow/iu,/session core/iu,/memory engine/iu,/retrieval/iu],kn=[/\bdùng\b/iu,/\btách\b/iu,/\bthay\b/iu,/\bchuyển\b/iu,/\blưu\b/iu,/\bmap\b/iu,/\buse\b/iu,/\bsplit\b/iu,/\bstore\b/iu,/\breplace\b/iu,/\bmove\b/iu],xn=[/đường dẫn/iu,/\bpath\b/iu,/\bport\b/iu,/\bendpoint\b/iu,/\bdomain\b/iu,/\bbucket\b/iu,/\brepository\b/iu,/\brepo\b/iu,/\bbranch\b/iu,/\/[A-Za-z0-9._/-]{4,}/u],In=[/\blà\b/iu,/\bở\b/iu,/\bdùng\b/iu,/\bnằm\b/iu,/\bis\b/iu,/\buse\b/iu,/located/iu,/runs on/iu],qe=new Set(["content","text","message","prompt","summary","description","reason","title","last_assistant_message","lastAssistantMessage","input_messages","inputMessages"]),Pn=new Set(["payload","data","content","message","messages","parts","summary"]);function k(t,e){return e.some(n=>n.test(t))}function Je(t){return t.normalize("NFKC").replace(/\r/g,"").replace(/^[\s>*#\-•]+/u,"").replace(/\s+/g," ").trim()}function On(t){return Je(t).toLowerCase().replace(/[^\p{L}\p{N}:/._-]+/gu," ").replace(/\s+/g," ").trim()}function An(t){return!(t.length<12||t.length>1e3||(t.match(new RegExp("\\p{L}","gu"))??[]).length<6||/^(?:https?:\/\/\S+|[A-Za-z0-9+/=]{80,})$/u.test(t))}function me(t,e,n,r=0){if(!(r>6)){if(typeof t=="string"){(!e||qe.has(e))&&n.push(t);return}if(Array.isArray(t)){for(let s of t.slice(0,50))me(s,e,n,r+1);return}if(!(!t||typeof t!="object"))for(let[s,o]of Object.entries(t))(qe.has(s)||Pn.has(s))&&me(o,s,n,r+1)}}function En(t){let e=[];me(t.data,void 0,e);let n=[],r=new Set;for(let s of e)for(let o of s.split(/\n+|(?<=[.!?])\s+/u)){let i=Je(o);if(An(i)&&!r.has(i)&&(r.add(i),n.push(i),n.length>=50))return n}return n}function De(t){return(t.role??(typeof t.data.role=="string"?t.data.role:"")).toLowerCase()}function Mn(t,e,n){if(n.type==="decision")return{kind:"decision",confidence:1};if(n.type==="todo")return{kind:"todo",confidence:1};let r=e==="user"||n.type==="user_prompt",s=e==="assistant"||n.type==="assistant_message";return r&&k(t,Be)?{kind:"rule",confidence:.98}:r&&k(t,vn)?{kind:"rule",confidence:.92}:k(t,bn)?{kind:k(t,Ke)?"architecture":"decision",confidence:r?.93:.86}:r&&k(t,wn)?{kind:"todo",confidence:.87}:k(t,Ke)&&k(t,kn)?{kind:"architecture",confidence:r?.88:.82}:s&&k(t,jn)?{kind:"fix",confidence:.8}:r&&k(t,xn)&&k(t,In)?{kind:"context",confidence:.79}:null}function Rn(t){switch(t){case"rule":return"rule";case"decision":case"architecture":return"decision";case"todo":return"todo";case"fix":case"context":return"code"}}function Nn(t,e,n){return t==="rule"&&k(n,Be)?"critical":t==="architecture"||t==="decision"||t==="rule"?"high":t==="fix"||t==="context"?"normal":Fe(e,n)}function Ve(t,e){let n=[],r=new Set,s=new Map;for(let o of e){let i=typeof o.data.messageId=="string"?o.data.messageId:void 0,c=De(o);i&&c&&s.set(i,c)}for(let o of e){let i=De(o),c=typeof o.data.messageId=="string"?o.data.messageId:void 0;!i&&c&&(i=s.get(c)??"");for(let u of En(o)){let a=Mn(u,i,o);if(!a||a.confidence<.75)continue;let m=Rn(a.kind),l=On(u),f=v([t.projectId,a.kind,l].join("|"));if(r.has(f))continue;r.add(f);let h=o.provenance.sourcePath?[o.provenance.sourcePath]:[],S=o.sourceEventId?[o.sourceEventId]:[];n.push({version:1,fingerprint:f,projectId:t.projectId,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,kind:a.kind,type:m,content:u,confidence:a.confidence,importance:Nn(a.kind,m,u),tags:[m],provenance:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventIds:[o.id],sourceEventIds:S,sourcePaths:h,firstSequence:o.sequence,lastSequence:o.sequence},createdAt:o.timestamp})}}return n}function Ue(t){return String(t).padStart(12,"0")}function Tn(t){return t.remotePrefix.replace("/sessions/","/memory/learned/")}var Y=class{constructor(e){this.storage=e}storage;async write(e,n,r){if(r.length===0||n.length===0)return null;let s=Math.min(...n.map(m=>m.sequence)),o=Math.max(...n.map(m=>m.sequence)),i={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:s,lastSequence:o,candidateCount:r.length,candidates:r},c=JSON.stringify(i,null,2)+`
|
|
13
|
+
`,u=v(r.map(m=>m.fingerprint).sort().join("|")).slice(0,16),a=[Tn(e),"batches",`${Ue(s)}-${Ue(o)}-${u}.json`].join("/");return await this.storage.exists(a)||await this.storage.put(a,c,"application/json"),a}};function Wn(t,e){if(!_n(t))return{events:[],nextOffset:e};let n=zn(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=$n(t,"r");try{Ln(i,o,0,s,r)}finally{Cn(i)}let c=o.toString("utf8"),u=c.lastIndexOf(`
|
|
14
|
+
`);if(u<0)return{events:[],nextOffset:r};let a=c.slice(0,u+1);return{events:a.split(`
|
|
15
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var G=class{constructor(e){this.options=e;this.journal=new Y(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["memory.learner.offset"]??0),r=Number.isFinite(n)?n:0,s=Wn(this.options.wal.eventsFile,r);if(s.events.length===0)return{scannedEvents:0,candidates:0,journalWritten:!1,nextOffset:s.nextOffset};let o=Ve(this.options.identity,s.events),i=!1;return o.length>0&&(i=!!await this.journal.write(this.options.identity,s.events,o)),this.options.wal.setSourceCursor("memory.learner.offset",s.nextOffset),{scannedEvents:s.events.length,candidates:o.length,journalWritten:i,nextOffset:s.nextOffset}}};import{closeSync as Vn,existsSync as Un,openSync as Hn,readSync as Yn,statSync as Gn}from"node:fs";var Fn=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function C(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function Ye(t){return C(t).toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function T(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))T(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Fn.has(r)||["data","payload","parts","messages"].includes(r))&&T(s,e,n+1)}}function X(t){return/\b(cancelled|canceled)\b|đã hủy|bỏ qua/iu.test(t)?"cancelled":/\b(blocked|blocker)\b|đang vướng|bị vướng|đang kẹt|chưa thể/iu.test(t)?"blocked":/\b(completed|complete|done|finished|passed)\b|hoàn thành|hoàn tất|đã xong|đã làm xong|\bxong\b/iu.test(t)?"completed":/\bin[\s_-]*progress\b|working on|đang làm|đang thực hiện|đang xử lý|đang triển khai/iu.test(t)?"in_progress":"pending"}function He(t){let e=C(t);return/^(?:đang\s+làm|đang\s+thực\s+hiện|đang\s+xử\s+lý|đang\s+triển\s+khai|hoàn\s+thành|hoàn\s+tất|đã\s+xong|đã\s+làm\s+xong|xong|pending|in[\s_-]*progress|completed|complete|done|finished|blocked|cancelled|canceled)[.!]*$/iu.test(e)}function w(t,e,n,r,s={}){let o=C(r),i=s.key??Ye(o);return{version:1,id:v([t.projectId,n,i,e.id,o,s.status??"",s.order??""].join("|")).slice(0,32),projectId:t.projectId,kind:n,key:i,text:o,status:s.status,order:s.order,confidence:s.confidence??.85,occurredAt:e.timestamp,sequence:e.sequence,agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId}}function Kn(t,e,n){let r=C(n);if(r.length<5||r.length>1200)return[];let s=[],o=/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r),i=r.match(/^(?:mục tiêu|goal|objective)\s*(?::|-)\s*(.+)$/iu);i?.[1]&&s.push(w(t,e,"goal",i[1],{confidence:.97}));let c=r.match(/^(?:kế hoạch|plan)\s*(?::|-)\s*(.+)$/iu);c?.[1]&&s.push(w(t,e,"plan",c[1],{confidence:.95}));let u=/\b(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?([^.;\n]{0,220})/giu,a;for(;!o&&(a=u.exec(r));){let f=Number(a[1]),h=C(a[2]??""),S=h&&!He(h)?`Phase ${f} - ${h}`:`Phase ${f}`;s.push(w(t,e,"phase",S,{key:`phase:${f}`,order:f,status:X(r),confidence:.93}))}let m=n.match(/^\s*[-*]\s*\[([ xX])\]\s*(.+)$/u);m?.[2]&&s.push(w(t,e,"task",m[2],{status:m[1].trim()?"completed":X(m[2]),confidence:.96}));let l=r.match(/^(?:todo|task|việc)\s*(\d+)?(?:\s*[:.\-–—]\s*|\s+)(.+)$/iu);if(l?.[2]){let f=l[1]?Number(l[1]):void 0,h=C(l[2]),S=He(h);s.push(w(t,e,"task",S&&f!==void 0?`TODO ${f}`:h,{key:f!==void 0?`task:${f}`:Ye(h),order:f,status:X(r),confidence:.93}))}if(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\b/iu.test(r)){let f=r.replace(/^(?:next|next action|next step|tiếp theo|bước tiếp theo|cần làm tiếp)\s*(?::|-)?\s*/iu,"");f&&s.push(w(t,e,"next_action",f,{confidence:.9}))}return/\b(blocker|blocked)\b|đang vướng|bị vướng|đang kẹt/iu.test(r)&&s.push(w(t,e,"blocker",r,{confidence:.9})),/\b(chú ý|lưu ý|warning|attention|cẩn thận)\b/iu.test(r)&&s.push(w(t,e,"warning",r,{confidence:.88})),/\b(chốt|quyết định|decided|decision)\b/iu.test(r)&&s.push(w(t,e,"decision",r,{confidence:.9})),s}function Ge(t,e){if(e.length===0)return[];let n=[],r=new Set;function s(i){r.has(i.id)||(r.add(i.id),n.push(i))}for(let i of e){if(i.type==="decision"){let u=[];T(i.data,u);for(let a of u)s(w(t,i,"decision",a,{confidence:1}))}if(i.type==="todo"){let u=[];T(i.data,u);for(let a of u)s(w(t,i,"task",a,{status:X(a),confidence:1}))}if(["file_write","file_edit"].includes(i.type))for(let u of["filePath","path","file"]){let a=i.data[u];typeof a=="string"&&a&&s(w(t,i,"file",a,{confidence:1}))}if(i.type==="test"){let u=[];T(i.data,u);for(let a of u)s(w(t,i,"test",a,{confidence:1}))}let c=[];T(i.data,c);for(let u of c)for(let a of u.split(/\n+/u))for(let m of Kn(t,i,a))s(m)}let o=e[e.length-1];return s(w(t,o,"session",`${t.agent}:${t.nativeSessionId}`,{key:t.sessionKey,confidence:1})),n}function Xe(t){return String(t).padStart(12,"0")}var Z=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(a=>a.sequence)),s=Math.max(...n.map(a=>a.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,createdAt:new Date().toISOString(),firstSequence:r,lastSequence:s,observations:n},i=JSON.stringify(o,null,2)+`
|
|
16
|
+
`,c=v(n.map(a=>a.id).sort().join("|")).slice(0,16),u=[`projects/${e.projectId}`,"work","observations",e.agent,e.nativeSessionId,`${Xe(r)}-${Xe(s)}-${c}.json`].join("/");return await this.storage.exists(u)||await this.storage.put(u,i,"application/json"),u}};import{join as Ze}from"node:path";import{mkdirSync as qn}from"node:fs";function Dn(t){return t.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function _(t,e=20){let n=[],r=new Set;for(let s of t.slice().reverse()){let o=Dn(s);if(!(!o||r.has(o))&&(r.add(o),n.push(s),n.length>=e))break}return n.reverse()}function Bn(t){return t.kind==="phase"?/^Phase\s+\d+$/iu.test(t.text):t.kind==="task"?/^(?:TODO|Task|Việc)\s+\d+$/iu.test(t.text):!1}function Qe(t,e){let n=e.status??t?.status??"pending",r=n;t&&(t.status==="completed"&&n!=="completed"?r="completed":n==="pending"&&(t.status==="in_progress"||t.status==="blocked")&&(r=t.status));let s=t&&Bn(e)?t.title:e.text;return{id:t?.id??v(e.key).slice(0,24),title:s,status:r,order:e.order??t?.order,confidence:Math.max(e.confidence,t?.confidence??0),updatedAt:e.occurredAt,updatedBy:{agent:e.agent,nativeSessionId:e.nativeSessionId,eventId:e.eventId}}}async function Jn(t,e){let n=`projects/${t.id}/work/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await e.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}async function Q(t,e){let r=(await Jn(t,e)).flatMap(p=>p.observations).sort((p,j)=>{let he=p.occurredAt.localeCompare(j.occurredAt);if(he!==0)return he;let Se=p.sequence-j.sequence;return Se!==0?Se:p.id.localeCompare(j.id)}),s=new Map,o=new Map,i,c,u,a=[],m=[],l=[],f=[],h=[],S=[];for(let p of r)switch(p.kind){case"goal":i=p.text;break;case"plan":c=p.text;break;case"phase":s.set(p.key,Qe(s.get(p.key),p));break;case"task":o.set(p.key,Qe(o.get(p.key),p));break;case"decision":a.push(p.text);break;case"blocker":m.push(p.text);break;case"warning":l.push(p.text);break;case"next_action":f.push(p.text);break;case"file":h.push(p.text);break;case"test":S.push(p.text);break;case"session":u={agent:p.agent,nativeSessionId:p.nativeSessionId,sessionKey:p.sessionKey,updatedAt:p.occurredAt};break}let g=Array.from(s.values()).sort((p,j)=>(p.order??Number.MAX_SAFE_INTEGER)-(j.order??Number.MAX_SAFE_INTEGER)),d=Array.from(o.values()).sort((p,j)=>(p.order??Number.MAX_SAFE_INTEGER)-(j.order??Number.MAX_SAFE_INTEGER)),y=g.find(p=>p.status==="in_progress")??g.find(p=>p.status==="blocked")??g.find(p=>p.status==="pending"),b=d.find(p=>p.status==="in_progress")??d.find(p=>p.status==="blocked")??d.find(p=>p.status==="pending"),M=_([...f,...b?[b.title]:[],...!b&&y?[y.title]:[],...d.filter(p=>p.status==="pending").slice(0,5).map(p=>p.title)],8),N=_([...m,...g.filter(p=>p.status==="blocked").map(p=>p.title),...d.filter(p=>p.status==="blocked").map(p=>p.title)],20),P={version:1,projectId:t.id,projectName:t.name,goal:i,plan:c,phases:g,tasks:d,decisions:_(a,20),blockers:N,warnings:_(l,20),nextActions:M,filesTouched:_(h,30),tests:_(S,20),currentPhase:y,currentTask:b,progress:{phasesTotal:g.length,phasesCompleted:g.filter(p=>p.status==="completed").length,tasksTotal:d.length,tasksCompleted:d.filter(p=>p.status==="completed").length,blocked:g.filter(p=>p.status==="blocked").length+d.filter(p=>p.status==="blocked").length},lastSession:u,updatedAt:r.length?r[r.length-1].occurredAt:new Date().toISOString()},R=Ze(t.rootPath,".toolnet","work");return qn(R,{recursive:!0}),O(Ze(R,"current.json"),P),await e.put(`projects/${t.id}/work/current.json`,JSON.stringify(P,null,2)+`
|
|
17
|
+
`,"application/json"),P}async function et(t,e){let n=await e.getText(`projects/${t.id}/work/current.json`);if(!n)return null;try{return JSON.parse(n)}catch{return null}}function Xn(t,e){if(!Un(t))return{events:[],nextOffset:e};let n=Gn(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=n-r,o=Buffer.alloc(s),i=Hn(t,"r");try{Yn(i,o,0,s,r)}finally{Vn(i)}let c=o.toString("utf8"),u=c.lastIndexOf(`
|
|
18
|
+
`);if(u<0)return{events:[],nextOffset:r};let a=c.slice(0,u+1);return{events:a.split(`
|
|
19
|
+
`).filter(Boolean).flatMap(l=>{try{return[JSON.parse(l)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(a,"utf8")}}var ee=class{constructor(e){this.options=e;this.journal=new Z(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.continuity.offset"]??0),r=Xn(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=Ge(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await Q(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.continuity.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{closeSync as ir,existsSync as ar,openSync as cr,readSync as ur,statSync as pr}from"node:fs";var Zn=new Set(["content","text","message","prompt","summary","description","title","reason","last_assistant_message","lastAssistantMessage"]);function $(t){return t.normalize("NFKC").replace(/\s+/g," ").replace(/^[\s>*#•-]+/u,"").trim()}function fe(t,e,n=0){if(!(n>6)){if(typeof t=="string"){e.push(t);return}if(Array.isArray(t)){for(let r of t.slice(0,50))fe(r,e,n+1);return}if(!(!t||typeof t!="object"))for(let[r,s]of Object.entries(t))(Zn.has(r)||["data","payload","parts","messages"].includes(r))&&fe(s,e,n+1)}}function x(t,e,n,r,s,o=.95){let i=$(r);return{version:1,id:v([t.projectId,n,s.type,s.key??"",i.toLowerCase(),e.id].join("|")).slice(0,32),projectId:t.projectId,kind:n,value:i,scope:s.type,scopeKey:s.key,scopeOrder:s.order,confidence:o,evidence:{agent:t.agent,nativeSessionId:t.nativeSessionId,sessionKey:t.sessionKey,eventId:e.id,sourceEventId:e.sourceEventId,sequence:e.sequence,occurredAt:e.timestamp}}}function I(t,e){let n=t.toLowerCase();for(let r of e){let s=r.toLowerCase();if(n.startsWith(`${s}:`)||n.startsWith(`${s} -`)||n.startsWith(`${s} \u2014`))return $(t.slice(r.length+1))}return null}function Qn(t){let e=t.trimStart();return e.startsWith("- ")||e.startsWith("* ")||/^\d+[.)]\s+/u.test(e)}function er(t){return $(t.trim().replace(/^[-*]\s+/u,"").replace(/^\d+[.)]\s+/u,""))}function tt(t,e){let n=[],r=new Set;function s(o){!o.value||o.value.length<3||r.has(o.id)||(r.add(o.id),n.push(o))}for(let o of e){let i=[];fe(o.data,i);for(let c of i){let u={type:"project"},a=null;for(let m of c.split(/\r?\n/u)){let l=$(m);if(!l){a=null;continue}let f=l.match(/^(?:phase|giai đoạn|giai doan|stage)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(f){let j=Number(f[1]);u={type:"phase",key:`phase:${j}`,order:j,title:$(f[2]??"")},a=null;continue}let h=l.match(/^(?:todo|task|việc)\s*(\d+)\s*(?:[:\-–—]\s*)?(.*)$/iu);if(h){let j=Number(h[1]);u={type:"task",key:`task:${j}`,order:j,title:$(h[2]??"")},a=null;continue}let S=I(l,["mission","s\u1EE9 m\u1EC7nh","m\u1EE5c ti\xEAu t\u1ED5ng th\u1EC3","m\u1EE5c ti\xEAu project","project goal"]);if(S){s(x(t,o,"mission",S,{type:"project"},.99)),a=null;continue}let g=I(l,["current objective","active objective","m\u1EE5c ti\xEAu hi\u1EC7n t\u1EA1i","objective","m\u1EE5c ti\xEAu","m\u1EE5c \u0111\xEDch"]);if(g){s(x(t,o,u.type==="phase"?"phase_objective":"objective",g,u,.98)),a=null;continue}let d=I(l,["why","why this","why this phase","reason","rationale","v\xEC sao","l\xFD do","t\u1EA1i sao","\xFD ngh\u0129a"]);if(d){s(x(t,o,u.type==="phase"?"phase_why":"why",d,u,.98)),a=null;continue}let y=I(l,["desired outcome","final outcome","k\u1EBFt qu\u1EA3 cu\u1ED1i","k\u1EBFt qu\u1EA3 mong mu\u1ED1n","m\u1EE5c ti\xEAu cu\u1ED1i"]);if(y){s(x(t,o,"desired_outcome",y,{type:"project"},.98)),a=null;continue}let b=I(l,["plan rationale","approach rationale","why this approach","t\u1EA1i sao ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn h\u01B0\u1EDBng n\xE0y","l\xFD do ch\u1ECDn ki\u1EBFn tr\xFAc"]);if(b){s(x(t,o,"plan_rationale",b,{type:"project"},.98)),a=null;continue}let M=I(l,["deliverable","output","k\u1EBFt qu\u1EA3 c\u1EA7n \u0111\u1EA1t","ph\u1EA3i t\u1EA1o ra","\u0111\u1EA7u ra"]);if(M){s(x(t,o,"phase_deliverable",M,u,.97)),a=null;continue}let N=I(l,["acceptance criteria","definition of done","done khi","ho\xE0n th\xE0nh khi","ti\xEAu ch\xED ho\xE0n th\xE0nh"]);if(N){s(x(t,o,"acceptance_criterion",N,u,.98)),a="acceptance_criterion";continue}let P=I(l,["depends on","dependency","dependencies","ph\u1EE5 thu\u1ED9c","c\u1EA7n c\xF3 tr\u01B0\u1EDBc"]);if(P){s(x(t,o,"dependency",P,u,.97)),a="dependency";continue}let R=I(l,["open question","open questions","c\xE2u h\u1ECFi m\u1EDF","ch\u01B0a quy\u1EBFt \u0111\u1ECBnh","ch\u01B0a r\xF5"]);if(R){s(x(t,o,"open_question",R,u,.95)),a="open_question";continue}let p=I(l,["constraint","constraints","r\xE0ng bu\u1ED9c","gi\u1EDBi h\u1EA1n"]);if(p){s(x(t,o,"constraint",p,u,.97)),a="constraint";continue}if(/^(?:acceptance criteria|definition of done|done khi|tiêu chí hoàn thành)\s*:?\s*$/iu.test(l)){a="acceptance_criterion";continue}if(/^(?:dependencies|dependency|phụ thuộc)\s*:?\s*$/iu.test(l)){a="dependency";continue}if(/^(?:open questions|open question|câu hỏi mở)\s*:?\s*$/iu.test(l)){a="open_question";continue}if(/^(?:constraints|constraint|ràng buộc)\s*:?\s*$/iu.test(l)){a="constraint";continue}if(a&&Qn(m)){s(x(t,o,a,er(m),u,.96));continue}a=null}}}return n}function nt(t){return String(t).padStart(12,"0")}var te=class{constructor(e){this.storage=e}storage;async write(e,n){if(n.length===0)return null;let r=Math.min(...n.map(u=>u.evidence.sequence)),s=Math.max(...n.map(u=>u.evidence.sequence)),o={version:1,projectId:e.projectId,agent:e.agent,nativeSessionId:e.nativeSessionId,sessionKey:e.sessionKey,firstSequence:r,lastSequence:s,createdAt:new Date().toISOString(),observations:n},i=v(n.map(u=>u.id).sort().join("|")).slice(0,16),c=[`projects/${e.projectId}`,"work","semantic","observations",e.agent,e.nativeSessionId,`${nt(r)}-${nt(s)}-${i}.json`].join("/");return await this.storage.exists(c)||await this.storage.put(c,JSON.stringify(o,null,2)+`
|
|
20
|
+
`,"application/json"),c}};import{mkdirSync as tr}from"node:fs";import{join as rt}from"node:path";function nr(t){return{value:t.value,confidence:t.confidence,evidence:t.evidence}}function rr(t,e){if(!e)return!0;let n=t.evidence.occurredAt.localeCompare(e.evidence.occurredAt);return n!==0?n>0:t.evidence.sessionKey===e.evidence.sessionKey?t.evidence.sequence>=e.evidence.sequence:t.confidence>=e.confidence}function A(t,e){return rr(e,t)?e:t}function E(t,e=30){let n=new Set,r=[];for(let s of t){let o=s.value.normalize("NFKC").toLowerCase().replace(/\s+/g," ").trim();!o||n.has(o)||(n.add(o),r.push(s))}return r.slice(-e)}async function sr(t,e){let n=`projects/${t.id}/work/semantic/observations/`,r=await e.list(n),s=[];for(let o of r.filter(i=>i.key.endsWith(".json")).sort((i,c)=>i.key.localeCompare(c.key))){let i=await e.getText(o.key);if(i)try{let c=JSON.parse(i);c.version===1&&Array.isArray(c.observations)&&s.push(c)}catch{}}return s}function or(t){return{key:t.scopeKey??`phase:${t.scopeOrder??0}`,order:t.scopeOrder??0,acceptanceCriteria:[],dependencies:[],openQuestions:[],constraints:[],notes:[]}}async function st(t,e){let r=(await sr(t,e)).flatMap(g=>g.observations).sort((g,d)=>{let y=g.evidence.occurredAt.localeCompare(d.evidence.occurredAt);return y!==0?y:g.evidence.sessionKey===d.evidence.sessionKey?g.evidence.sequence-d.evidence.sequence:g.id.localeCompare(d.id)}),s,o,i,c,u,a=new Map,m=[],l=[],f=[];for(let g of r){let d=nr(g);if(g.scope==="phase"&&g.scopeKey){let y=a.get(g.scopeKey)??or(g);switch(g.kind){case"phase_objective":y.objective=A(y.objective,d);break;case"phase_why":y.why=A(y.why,d);break;case"phase_deliverable":y.deliverable=A(y.deliverable,d);break;case"acceptance_criterion":y.acceptanceCriteria.push(d);break;case"dependency":y.dependencies.push(d);break;case"open_question":y.openQuestions.push(d);break;case"constraint":y.constraints.push(d);break;case"note":y.notes.push(d);break}a.set(y.key,y);continue}switch(g.kind){case"mission":s=A(s,d);break;case"objective":o=A(o,d);break;case"why":i=A(i,d);break;case"desired_outcome":c=A(c,d);break;case"plan_rationale":u=A(u,d);break;case"open_question":m.push(d);break;case"constraint":l.push(d);break;case"note":f.push(d);break}}for(let g of a.values())g.acceptanceCriteria=E(g.acceptanceCriteria,20),g.dependencies=E(g.dependencies,15),g.openQuestions=E(g.openQuestions,15),g.constraints=E(g.constraints,15),g.notes=E(g.notes,20);let h={version:1,projectId:t.id,projectName:t.name,mission:s,activeObjective:o,why:i,desiredOutcome:c,planRationale:u,phases:Array.from(a.values()).sort((g,d)=>g.order-d.order),openQuestions:E(m,20),constraints:E(l,20),notes:E(f,20),updatedAt:r.length?r[r.length-1].evidence.occurredAt:new Date().toISOString()},S=rt(t.rootPath,".toolnet","work");return tr(S,{recursive:!0}),O(rt(S,"semantic-current.json"),h),await e.put(`projects/${t.id}/work/semantic/current.json`,JSON.stringify(h,null,2)+`
|
|
21
|
+
`,"application/json"),h}function lr(t,e){if(!ar(t))return{events:[],nextOffset:e};let n=pr(t).size,r=Number.isFinite(e)?Math.max(0,e):0;if(r>n&&(r=0),r===n)return{events:[],nextOffset:n};let s=Buffer.alloc(n-r),o=cr(t,"r");try{ur(o,s,0,s.length,r)}finally{ir(o)}let i=s.toString("utf8"),c=i.lastIndexOf(`
|
|
22
|
+
`);if(c<0)return{events:[],nextOffset:r};let u=i.slice(0,c+1);return{events:u.split(`
|
|
23
|
+
`).filter(Boolean).flatMap(a=>{try{return[JSON.parse(a)]}catch{return[]}}),nextOffset:r+Buffer.byteLength(u,"utf8")}}var ne=class{constructor(e){this.options=e;this.journal=new te(e.storage)}options;journal;async learnNew(){let e=this.options.wal.loadState(),n=Number(e.sourceCursors["work.semantic.offset"]??0),r=lr(this.options.wal.eventsFile,Number.isFinite(n)?n:0);if(r.events.length===0)return{scannedEvents:0,observations:0,journalWritten:!1,reconciled:!1,nextOffset:r.nextOffset};let s=tt(this.options.identity,r.events),o=!1,i=!1;return s.length>0&&(o=!!await this.journal.write(this.options.identity,s),o&&(await st(this.options.project,this.options.storage),i=!0)),this.options.wal.setSourceCursor("work.semantic.offset",r.nextOffset),{scannedEvents:r.events.length,observations:s.length,journalWritten:o,reconciled:i,nextOffset:r.nextOffset}}};import{mkdirSync as wr}from"node:fs";import{join as ge}from"node:path";import{existsSync as at,mkdirSync as dr,readFileSync as mr,statSync as ot,writeFileSync as fr}from"node:fs";import{dirname as gr,join as yr}from"node:path";var it=64*1024,hr=`# ToolNet Project Operating Manual
|
|
24
|
+
|
|
25
|
+
This file contains persistent instructions for AI agents working on this project.
|
|
26
|
+
|
|
27
|
+
## Critical Rules
|
|
28
|
+
|
|
29
|
+
<!--
|
|
30
|
+
Examples:
|
|
31
|
+
|
|
32
|
+
- [enforce] Never edit production files directly.
|
|
33
|
+
- [enforce] Edit source only in /path/to/source.
|
|
34
|
+
- [enforce] Deploy only with ./deploy.sh --apply
|
|
35
|
+
-->
|
|
36
|
+
|
|
37
|
+
## Workflow
|
|
38
|
+
|
|
39
|
+
<!--
|
|
40
|
+
Describe the correct working process.
|
|
41
|
+
-->
|
|
42
|
+
|
|
43
|
+
## Architecture
|
|
44
|
+
|
|
45
|
+
<!--
|
|
46
|
+
Important architecture conventions.
|
|
47
|
+
-->
|
|
48
|
+
|
|
49
|
+
## Verification
|
|
50
|
+
|
|
51
|
+
<!--
|
|
52
|
+
Tests / QA required after changes.
|
|
53
|
+
-->
|
|
54
|
+
|
|
55
|
+
## Known Gotchas
|
|
56
|
+
|
|
57
|
+
<!--
|
|
58
|
+
Things an AI agent should always remember.
|
|
59
|
+
-->
|
|
60
|
+
|
|
61
|
+
## Preferences
|
|
62
|
+
|
|
63
|
+
<!--
|
|
64
|
+
- [advisory] Prefer small focused files.
|
|
65
|
+
-->
|
|
66
|
+
`;function ct(t){return yr(t.rootPath,".toolnet","PROJECT.md")}function Sr(t){return t.normalize("NFKC").replace(/\s+/g," ").trim()}function vr(t){let e=[],n=new Set,r=/^\s*[-*]\s+\[(enforce|advisory)\]\s+(.+?)\s*$/gimu,s;for(;s=r.exec(t);){let o=s[1].toLowerCase(),i=Sr(s[2]);if(!i)continue;let c=`${o}:${i.toLowerCase()}`;n.has(c)||(n.add(c),e.push({id:v(c).slice(0,24),mode:o,text:i,source:"manual"}))}return e}function br(t){let e=ct(t);return at(e)||(dr(gr(e),{recursive:!0}),fr(e,hr,{encoding:"utf8",mode:384})),e}function ut(t,e=!1){let n=e?br(t):ct(t);if(!at(n))return null;if(ot(n).size>it)throw new Error(`PROJECT.md exceeds ${it} bytes`);let s=mr(n,"utf8");return{path:n,content:s,digest:v(s),rules:vr(s),bytes:Buffer.byteLength(s,"utf8"),updatedAt:new Date(ot(n).mtimeMs).toISOString()}}function jr(t){return{goal:t.goal,plan:t.plan,phases:t.phases.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),tasks:t.tasks.map(e=>({id:e.id,title:e.title,status:e.status,order:e.order})),decisions:t.decisions,blockers:t.blockers,warnings:t.warnings,nextActions:t.nextActions,filesTouched:t.filesTouched,tests:t.tests}}function kr(t){return t.phases.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.tasks.some(e=>e.status==="pending"||e.status==="in_progress"||e.status==="blocked")||t.nextActions.length>0||t.blockers.length>0}var re=class{constructor(e){this.options=e}options;async capture(e,n){let r=await et(this.options.project,this.options.storage);if(r||(r=await Q(this.options.project,this.options.storage)),!kr(r))return null;let s=ut(this.options.project,!1),o=s?s.rules.filter(f=>f.mode==="enforce").map(f=>f.text):[],i=v(JSON.stringify(jr(r))),c=v([this.options.project.id,this.options.identity.sessionKey,i].join("|")).slice(0,24),u=new Date().toISOString(),a={version:1,id:c,projectId:this.options.project.id,projectName:this.options.project.name,createdAt:u,reason:e,sourceSession:{agent:this.options.identity.agent,nativeSessionId:this.options.identity.nativeSessionId,sessionKey:this.options.identity.sessionKey,sequence:n},goal:r.goal,plan:r.plan,progress:r.progress,currentPhase:r.currentPhase,currentTask:r.currentTask,incompletePhases:r.phases.filter(f=>f.status!=="completed"&&f.status!=="cancelled"),incompleteTasks:r.tasks.filter(f=>f.status!=="completed"&&f.status!=="cancelled"),nextActions:r.nextActions.slice(0,10),blockers:r.blockers.slice(0,10),decisions:r.decisions.slice(-10),warnings:r.warnings.slice(-10),attention:[...o,...r.warnings].slice(0,20),filesTouched:r.filesTouched.slice(-20),tests:r.tests.slice(-15),stateDigest:i},m=`projects/${this.options.project.id}/work/handoffs/${c}.json`;await this.options.storage.exists(m)||await this.options.storage.put(m,JSON.stringify(a,null,2)+`
|
|
67
|
+
`,"application/json"),await this.options.storage.put(`projects/${this.options.project.id}/work/handoff-latest.json`,JSON.stringify(a,null,2)+`
|
|
68
|
+
`,"application/json");let l=ge(this.options.project.rootPath,".toolnet","work","handoffs");return wr(l,{recursive:!0}),O(ge(l,`${c}.json`),a),O(ge(this.options.project.rootPath,".toolnet","work","handoff-latest.json"),a),a}};var se=class{identity;wal;remote;sanitizer=new z;learner;continuity;semantic;handoff;title;metadata;constructor(e){this.identity=$e(e.project,e.agent,e.nativeSessionId),this.title=e.title,this.metadata=this.sanitizer.sanitizeValue(e.metadata??{}),this.wal=new H(this.identity),this.remote=new U(e.storage,e.maxEventsPerChunk??100,e.maxChunkBytes??512*1024),this.learner=new G({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.continuity=new ee({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.semantic=new ne({project:e.project,storage:e.storage,identity:this.identity,wal:this.wal}),this.handoff=new re({project:e.project,storage:e.storage,identity:this.identity})}sanitizeEvent(e){let n=e.provenance?{...e.provenance,metadata:this.sanitizer.sanitizeValue(e.provenance.metadata)}:void 0;return{...e,data:this.sanitizer.sanitizeValue(e.data??{}),provenance:n}}start(e={}){let n=this.wal.loadState();return this.record({type:n.lastSequence===0?"session_start":"session_resume",data:e,provenance:{source:this.identity.agent}})}record(e){return this.wal.append([this.sanitizeEvent(e)])[0]}recordMany(e){return this.wal.append(e.map(n=>this.sanitizeEvent(n)))}setSourceCursor(e,n){this.wal.setSourceCursor(e,n)}async flush(){let e=this.wal.readPending(),n=this.wal.loadState(),r=await this.remote.append(this.identity,e.events,n.sourceCursors,{title:this.title,metadata:this.metadata});if(e.events.length>0){let s=e.events[e.events.length-1];this.wal.markRemote(s.sequence,e.endOffset)}if(process.env.TOOLNET_SESSION_LEARNING!=="0")try{await this.learner.learnNew()}catch{}if(process.env.TOOLNET_WORK_CONTINUITY!=="0")try{await this.continuity.learnNew()}catch{}if(process.env.TOOLNET_SEMANTIC_CONTINUITY!=="0")try{await this.semantic.learnNew()}catch{}if(process.env.TOOLNET_SMART_HANDOFF!=="0"&&e.events.length>0)try{let s=e.events[e.events.length-1],o=["session_idle","session_end","session_compact"].includes(s.type)?s.type:"checkpoint";await this.handoff.capture(o,s.sequence)}catch{}return r}async idle(e={}){return this.record({type:"session_idle",data:e,provenance:{source:this.identity.agent}}),this.flush()}async end(e={}){return this.record({type:"session_end",data:e,provenance:{source:this.identity.agent}}),this.flush()}status(){return this.wal.loadState()}recoverRemote(){return this.remote.recover(this.identity)}};import{existsSync as xr,openSync as Ir,closeSync as Pr,readSync as Or,statSync as Ar}from"node:fs";function Er(t){let e=typeof t.role=="string"?t.role:"",n=typeof t.type=="string"?t.type.toLowerCase():"";return e==="user"||n.includes("user")?"user_prompt":e==="assistant"||n.includes("assistant")||n.includes("model")?"assistant_message":n.includes("tool")||"toolCall"in t||"tool_call"in t?"tool_call":n.includes("error")?"error":"message"}function Mr(t){let e=[t.timestamp,t.createdAt,t.time,t.created_at];for(let n of e){if(typeof n=="string"){let r=new Date(n);if(!Number.isNaN(r.getTime()))return r.toISOString()}if(typeof n=="number"){let r=n;r<1e11&&(r*=1e3);let s=new Date(r);if(!Number.isNaN(s.getTime()))return s.toISOString()}}return new Date().toISOString()}function pt(t,e={offset:0}){if(!xr(t))return{events:[],nextOffset:e.offset,reset:!1};let n=Ar(t).size,r=e.offset>n,s=r?0:e.offset;if(s===n)return{events:[],nextOffset:n,reset:r};let o=n-s,i=Buffer.alloc(o),c=Ir(t,"r");try{Or(c,i,0,o,s)}finally{Pr(c)}let u=i.toString("utf8"),a=u.lastIndexOf(`
|
|
69
|
+
`);if(a<0)return{events:[],nextOffset:s,reset:r};let m=u.slice(0,a+1),l=Buffer.byteLength(m,"utf8"),f=[],h=0;for(let S of m.split(`
|
|
70
|
+
`)){if(!S)continue;let g=Buffer.byteLength(S+`
|
|
71
|
+
`,"utf8"),d=s+h;h+=g;let y;try{y=JSON.parse(S)}catch{f.push({type:"custom",sourceEventId:`transcript:${d}`,sourceSequence:d,data:{format:"raw-line",content:S},provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:d}});continue}let b=y&&typeof y=="object"&&!Array.isArray(y)?y:{value:y};f.push({type:Er(b),timestamp:Mr(b),role:typeof b.role=="string"?b.role:void 0,sourceEventId:`transcript:${d}`,sourceSequence:d,data:b,provenance:{source:"agy-transcript",sourcePath:t,sourceOffset:d}})}return{events:f,nextOffset:s+l,reset:r}}function Nr(t){return t==="~"?ye():t.startsWith("~/")?lt(ye(),t.slice(2)):t}async function oe(t){let e=t.conversationId.trim();if(!e)throw new Error("Agy conversationId is required");let n=Rr(Nr(t.transcriptPath)),r=new se({project:t.project,storage:t.storage,agent:"agy",nativeSessionId:e,metadata:{source:"antigravity-hook",transcriptPath:n,workspacePaths:t.workspacePaths??[],artifactDirectoryPath:t.artifactDirectoryPath,modelName:t.modelName}}),s=r.status(),o=s.sourceCursors["agy.transcript.offset"],i=o?Number(o):0,c=pt(n,{offset:Number.isFinite(i)?i:0}),u=[];s.lastSequence===0&&u.push({type:"session_start",sourceEventId:`agy:${e}:start`,data:{workspacePaths:t.workspacePaths??[],transcriptPath:n,modelName:t.modelName},provenance:{source:"antigravity-hook",sourcePath:n}}),c.reset&&u.push({type:"custom",sourceEventId:`agy:${e}:transcript-reset:${c.nextOffset}`,data:{event:"transcript_reset",transcriptPath:n},provenance:{source:"agy-transcript",sourcePath:n}}),u.push(...c.events),t.phase==="stop"&&(t.error&&u.push({type:"error",sourceEventId:["agy",e,"stop-error",t.terminationReason??"",c.nextOffset].join(":"),data:{error:t.error,terminationReason:t.terminationReason,fullyIdle:t.fullyIdle},provenance:{source:"antigravity-stop-hook"}}),t.fullyIdle&&u.push({type:"session_idle",sourceEventId:["agy",e,"idle",c.nextOffset].join(":"),data:{terminationReason:t.terminationReason,fullyIdle:!0},provenance:{source:"antigravity-stop-hook"}}));let a=r.recordMany(u);r.setSourceCursor("agy.transcript.offset",c.nextOffset),t.phase&&r.setSourceCursor("agy.last.phase",t.phase);let m=await r.flush();return{conversationId:e,imported:a.length,eventCount:m.eventCount,chunkCount:m.chunkCount,status:m.status,transcriptOffset:c.nextOffset,reset:c.reset}}function dt(t){return lt(ye(),".gemini","antigravity-cli","brain",t,".system_generated","logs","transcript.jsonl")}import{existsSync as Tr,mkdirSync as Cr,readFileSync as _r,writeFileSync as $r}from"node:fs";import{homedir as Lr}from"node:os";import{dirname as zr,join as Wr}from"node:path";function Fr(t){return`'${t.replace(/'/g,"'\\''")}'`}function mt(t={}){let e=t.hooksFile??Wr(Lr(),".gemini","config","hooks.json");Cr(zr(e),{recursive:!0});let n={};if(Tr(e))try{n=JSON.parse(_r(e,"utf8"))}catch(o){throw new Error(`Invalid existing Agy hooks.json: ${o instanceof Error?o.message:String(o)}`)}let r=t.binary??"toolnet-memory",s=`${Fr(r)} session:agy-hook`;return n["toolnet-memory"]={enabled:!0,PreInvocation:[{type:"command",command:`${s} pre`,timeout:15}],PostInvocation:[{type:"command",command:`${s} post`,timeout:15}],Stop:[{type:"command",command:`${s} stop`,timeout:30}]},$r(e,JSON.stringify(n,null,2)+`
|
|
72
|
+
`,{encoding:"utf8",mode:384}),e}import{existsSync as ft}from"node:fs";import{homedir as Kr}from"node:os";import{join as qr,resolve as gt}from"node:path";import{DatabaseSync as Dr}from"node:sqlite";function yt(t){if(t.startsWith("file://"))try{return decodeURIComponent(new URL(t).pathname)}catch{return t}return t}function Br(t){if(typeof t!="string"||!t)return[];try{let e=JSON.parse(t);if(Array.isArray(e))return e.filter(n=>typeof n=="string").map(yt)}catch{}return[yt(t)]}function Jr(t,e){let n=gt(t.rootPath);return e.some(r=>{let s=gt(r);return s===n||s.startsWith(n+"/")||n.startsWith(s+"/")})}async function ht(t,e,n=100){let r=process.env.AGY_SUMMARY_DB??qr(Kr(),".gemini","antigravity-cli","conversation_summaries.db");if(!ft(r))throw new Error(`Agy summary database not found: ${r}`);let s=new Dr(r,{readOnly:!0});s.exec("PRAGMA query_only = ON");let o=s.prepare(`
|
|
73
|
+
SELECT
|
|
74
|
+
conversation_id,
|
|
75
|
+
title,
|
|
76
|
+
workspace_uris,
|
|
77
|
+
agent_name,
|
|
78
|
+
last_user_input_time
|
|
79
|
+
FROM conversation_summaries
|
|
80
|
+
ORDER BY
|
|
81
|
+
last_user_input_time DESC
|
|
82
|
+
`).all();s.close();let i=[];for(let c of o){let u=typeof c.conversation_id=="string"?c.conversation_id:"";if(!u)continue;let a=Br(c.workspace_uris);if(!Jr(t,a))continue;let m=dt(u);if(ft(m)&&(i.push(await oe({project:t,storage:e,conversationId:u,transcriptPath:m,workspacePaths:a,modelName:typeof c.agent_name=="string"?c.agent_name:void 0,phase:"recover"})),i.length>=n))break}return i}function ie(t,e){let n=t.indexOf(e);return n>=0?t[n+1]:void 0}function Vr(t){let e=ve(),n=Me(Ae({provider:e.storage.provider,huggingface:e.storage.huggingface,localRoot:e.storage.localRoot}),{attempts:3});return new V(n,t.id,t.name,t.remote??t.name)}async function Ur(){let[t="help",...e]=process.argv.slice(2);if(t==="install-hooks"){let o=mt({binary:ie(e,"--bin")});console.log(`\u2705 Agy hooks installed: ${o}`);return}let n=ie(e,"--project")??process.cwd(),r=new D().detect(n),s=Vr(r);if(t==="sync"){let o=e[0],i=ie(e,"--transcript");if(!o||!i)throw new Error("Usage: sync <conversation-id> --transcript <path>");let c=await oe({project:r,storage:s,conversationId:o,transcriptPath:i,phase:"recover"});console.log(JSON.stringify(c,null,2));return}if(t==="recover"){let o=Number(ie(e,"--limit")??100),i=await ht(r,s,Number.isFinite(o)?o:100);console.log(JSON.stringify({project:r.name,sessions:i.length,imported:i.reduce((c,u)=>c+u.imported,0)},null,2));return}console.log(`Agy Session Adapter
|
|
83
|
+
|
|
84
|
+
Commands:
|
|
85
|
+
install-hooks
|
|
86
|
+
sync <conversation-id> --transcript <path>
|
|
87
|
+
recover [--project PATH] [--limit N]
|
|
88
|
+
`)}Ur().catch(t=>{console.error(t instanceof Error?t.message:t),process.exit(1)});
|