pi-coding-master 0.2.7
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 +50 -0
- package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py +80 -0
- package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py.CHANGELOG +1 -0
- package/core/god.agent.capability/@ABANDONED.brain.prefrontal.monitor/gpu_monitor.py.SPEC +3 -0
- package/core/god.agent.capability/hands.dev.writeissue/issue.ts +209 -0
- package/core/god.agent.capability/hands.dev.writeissue/issue.ts.SPEC +26 -0
- package/core/god.agent.capability/hands.files.changewatcher/watcher.ts +44 -0
- package/core/god.agent.capability/hands.files.changewatcher/watcher.ts.SPEC +25 -0
- package/core/god.pi.mod/cli/pi-completion.zsh +21 -0
- package/core/god.pi.mod/cli/pi-completion.zsh.CHANGELOG +1 -0
- package/core/god.pi.mod/cli/pi-people.sh +264 -0
- package/core/god.pi.mod/cli/pi-people.sh.LESSON +10 -0
- package/core/god.pi.mod/cli/pi-people.sh.SPEC +31 -0
- package/core/god.pi.mod/paths.ts +47 -0
- package/core/god.pi.mod/tui.mods.blockrender/blockrender.js +90 -0
- package/core/god.pi.mod/tui.mods.blockrender/blockrender.js.SPEC +29 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts +154 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.CHANGELOG +10 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.LESSON +12 -0
- package/core/god.pi.mod/tui.mods.footer.budget/budget_guard.ts.SPEC +26 -0
- package/core/god.pi.mod/tui.mods.footer.budget/footer-cny.CHANGELOG +39 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode-thinking.patch +55 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode-tools.patch +19 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode-tools.patch.CHANGELOG +1 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode.ts +50 -0
- package/core/god.pi.mod/tui.mods.viewmode/view_mode.ts.SPEC +12 -0
- package/core/god.pi.mod/tui.variants.userterminal/user_terminal.CHANGELOG +10 -0
- package/core/god.pi.mod/tui.variants.userterminal/user_terminal.ts +66 -0
- package/core/god.pi.mod/tui.variants.userterminal/user_terminal.ts.SPEC +31 -0
- package/core/index.ts +3 -0
- package/core/individual.bio.gene/dna.coded/coded.dna +257 -0
- package/core/individual.bio.gene/dna.coded/coded.dna.CHANGELOG +12 -0
- package/core/individual.bio.gene/dna.coded/coded.dna.SPEC +11 -0
- package/core/individual.bio.gene/dna.coded/core.dna +110 -0
- package/core/individual.bio.gene/dna.promotor/promotor.dna +117 -0
- package/core/individual.bio.gene/dna.promotor/promotor.dna.CHANGELOG +4 -0
- package/core/individual.bio.gene/dna.promotor/promotor.dna.SPEC +7 -0
- package/core/individual.bio.gene/dna.transpiler/transpiler.ts +395 -0
- package/core/individual.bio.gene/dna.transpiler/transpiler.ts.CHANGELOG +7 -0
- package/core/individual.bio.gene/dna.transpiler/transpiler.ts.SPEC +28 -0
- package/core/individual.bio.gene/gene.README +19 -0
- package/core/individual.bio.gene/rna/rna.json +536 -0
- package/core/individual.bio.gene/rna/rna.json.CHANGELOG +2 -0
- package/core/individual.bio.gene/rna/rna.json.SPEC +8 -0
- package/core/individual.bio.organs/blood.runtime/messages.ts +236 -0
- package/core/individual.bio.organs/blood.runtime/runtime.ts +173 -0
- package/core/individual.bio.organs/blood.runtime/runtime.ts.CHANGELOG +5 -0
- package/core/individual.bio.organs/blood.runtime/runtime.ts.SPEC +32 -0
- package/core/individual.bio.organs/brain.amygdala/amygdala.ts +25 -0
- package/core/individual.bio.organs/brain.amygdala/amygdala.ts.COMMENT +3 -0
- package/core/individual.bio.organs/brain.amygdala/amygdala.ts.SPEC +9 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus-launcher.sh.template +108 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts +166 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.CHANGELOG +12 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.LESSON +22 -0
- package/core/individual.bio.organs/brain.hippocampus/hippocampus.ts.SPEC +16 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts +879 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts.CHANGELOG +66 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts.LESSON +25 -0
- package/core/individual.bio.organs/brain.hippocampus/memory.ts.SPEC +46 -0
- package/core/individual.bio.organs/brain.hippocampus/sleep.ts +139 -0
- package/core/individual.bio.organs/brain.hippocampus/sleep.ts.CHANGELOG +11 -0
- package/core/individual.bio.organs/brain.hippocampus/sleep.ts.SPEC +16 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.SPEC +44 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts +73 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts.CHANGELOG +3 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/drafting.ts.SPEC +24 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/index.ts.CHANGELOG +3 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/main.ts +13 -0
- package/core/individual.bio.organs/brain.prefrontal.drafting/main.ts.SPEC +17 -0
- package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts +94 -0
- package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts.LESSON +13 -0
- package/core/individual.bio.organs/brain.senses.bioclock/bioclock.ts.SPEC +20 -0
- package/core/individual.bio.organs/brain.senses.subconscious/feed-format.SPEC +56 -0
- package/core/individual.bio.organs/brain.senses.subconscious/index.ts.CHANGELOG +13 -0
- package/core/individual.bio.organs/brain.senses.subconscious/spawner.ts +130 -0
- package/core/individual.bio.organs/brain.senses.subconscious/spawner.ts.SPEC +13 -0
- package/core/individual.bio.organs/brain.senses.subconscious/subconscious.ts +280 -0
- package/core/individual.bio.organs/brain.senses.subconscious/subconscious.ts.CHANGELOG +7 -0
- package/core/individual.bio.organs/brain.senses.subconscious/tools.ts +180 -0
- package/core/individual.bio.organs/brain.senses.subconscious/tools.ts.SPEC +3 -0
- package/core/individual.bio.organs/ears.listen/config.json +9 -0
- package/core/individual.bio.organs/ears.listen/config.json.CHANGELOG +1 -0
- package/core/individual.bio.organs/ears.listen/config.json.SPEC +3 -0
- package/core/individual.bio.organs/ears.listen/ears.ts.CHANGELOG +48 -0
- package/core/individual.bio.organs/ears.listen/ears_recorder.py.CHANGELOG +6 -0
- package/core/individual.bio.organs/ears.listen/index.ts +1 -0
- package/core/individual.bio.organs/ears.listen/index.ts.SPEC +16 -0
- package/core/individual.bio.organs/ears.listen/listen.ts +208 -0
- package/core/individual.bio.organs/ears.listen/listen.ts.SPEC +3 -0
- package/core/individual.bio.organs/ears.listen/listen_recorder.py +445 -0
- package/core/individual.bio.organs/ears.listen/listen_recorder.py.SPEC +7 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/events_pb2.py +38 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/events_pb2_grpc.py +24 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/rpcmeta_pb2.py +42 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/common/rpcmeta_pb2_grpc.py +24 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/ast_service_pb2.py +45 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/ast/ast_service_pb2_grpc.py +97 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/__init__.py +0 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/au_base_pb2.py +80 -0
- package/core/individual.bio.organs/ears.listen/python_protogen/products/understanding/base/au_base_pb2_grpc.py +24 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.TRUST +1 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.ts +70 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.ts.CHANGELOG +1 -0
- package/core/individual.bio.organs/hands.fileactions/authorize.ts.SPEC +3 -0
- package/core/individual.bio.organs/hands.fileactions/dir.README +13 -0
- package/core/individual.bio.organs/hands.fileactions/file_rules.json +23 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.README +12 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.ts +540 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.ts.CHANGELOG +25 -0
- package/core/individual.bio.organs/hands.fileactions/fileactions.ts.SPEC +30 -0
- package/core/individual.bio.organs/hands.fileactions/filewatch.ts +66 -0
- package/core/individual.bio.organs/hands.fileactions/filewatch.ts.SPEC +3 -0
- package/core/individual.bio.organs/hands.main/main.ts +18 -0
- package/core/individual.bio.organs/hands.main/main.ts.SPEC +20 -0
- package/core/individual.bio.organs/hands.sensitive/sensitive.ts +24 -0
- package/core/individual.bio.organs/hands.sensitive/sensitive.ts.CHANGELOG +2 -0
- package/core/individual.bio.organs/hands.sensitive/sensitive.ts.SPEC +3 -0
- package/core/individual.bio.organs/heart.interrupt/agent_start-loader-flicker.patch +13 -0
- package/core/individual.bio.organs/heart.interrupt/interactive-mode-loader.patch +11 -0
- package/core/individual.bio.organs/heart.interrupt/runner_esc.patch +10 -0
- package/core/individual.bio.organs/heart.interrupt/runner_esc.patch.SPEC +9 -0
- package/core/individual.bio.organs/heart.kernel/kernel.ts +253 -0
- package/core/individual.bio.organs/heart.kernel/kernel.ts.CHANGELOG +13 -0
- package/core/individual.bio.organs/heart.kernel/kernel.ts.SPEC +23 -0
- package/core/individual.bio.organs/heart.main/heart.main.CHANGELOG +43 -0
- package/core/individual.bio.organs/heart.main/heartbeat.ts +494 -0
- package/core/individual.bio.organs/heart.main/heartbeat.ts.LESSON +43 -0
- package/core/individual.bio.organs/heart.main/main.ts +8 -0
- package/core/individual.bio.organs/heart.main/main.ts.SPEC +19 -0
- package/core/individual.bio.organs/heart.main/process.ts +122 -0
- package/core/individual.bio.organs/heart.main/process.ts.CHANGELOG +2 -0
- package/core/individual.bio.organs/heart.main/process.ts.SPEC +24 -0
- package/core/individual.bio.organs/heart.main/remove_timeout.patch +110 -0
- package/core/individual.bio.organs/heart.main/stop.ts.CHANGELOG +3 -0
- package/core/individual.bio.organs/heart.main/stop.ts.SPEC +28 -0
- package/core/individual.bio.organs/mouth.speak/index.ts +1 -0
- package/core/individual.bio.organs/mouth.speak/index.ts.CHANGELOG +1 -0
- package/core/individual.bio.organs/mouth.speak/index.ts.SPEC +6 -0
- package/core/individual.bio.organs/mouth.speak/mouth.ts.CHANGELOG +15 -0
- package/core/individual.bio.organs/mouth.speak/mouth_recorder.py.CHANGELOG +1 -0
- package/core/individual.bio.organs/mouth.speak/speak.ts +180 -0
- package/core/individual.bio.organs/mouth.speak/speak.ts.SPEC +3 -0
- package/core/individual.bio.organs/mouth.speak/speak_recorder.py +35 -0
- package/core/individual.bio.organs/mouth.speak/speak_recorder.py.SPEC +3 -0
- package/core/individual.bio.organs/organs.README +110 -0
- package/core/package-lock.json +18 -0
- package/core/package.json +35 -0
- package/core/prompts/prompts.json +77 -0
- package/core/prompts/prompts.ts +44 -0
- package/core/prompts/prompts.ts.SPEC +9 -0
- package/core/society.world/.gitkeep +0 -0
- package/core/society.world/accessibility.claudecode/message-service.cjs +217 -0
- package/core/society.world/accessibility.claudecode/message-service.cjs.SPEC +7 -0
- package/core/society.world/accessibility.claudecode/send.ts +34 -0
- package/core/society.world/dollar.distribution.ubi/ubi.ts +55 -0
- package/core/society.world/dollar.main/dollar-service.cjs +185 -0
- package/core/society.world/dollar.main/main.ts +116 -0
- package/core/society.world/dollar.transaction/transaction.ts +71 -0
- package/core/society.world/space/space.ts +206 -0
- package/core/society.world/space/space.ts.SPEC +30 -0
- package/core/technology.laptop/#agent.macos.BLUEPRINT +278 -0
- package/core/technology.phone/apps.preinstalled/albums.FUTURE/albums.ts +69 -0
- package/core/technology.phone/apps.preinstalled/albums.FUTURE/albums.ts.SPEC +15 -0
- package/core/technology.phone/apps.preinstalled/calendar/calendar.ts +406 -0
- package/core/technology.phone/apps.preinstalled/calendar/calendar.ts.SPEC +22 -0
- package/core/technology.phone/apps.preinstalled/calendar/holiday-calendar.ts +529 -0
- package/core/technology.phone/apps.preinstalled/clock/clock.ts +132 -0
- package/core/technology.phone/apps.preinstalled/clock/clock.ts.SPEC +11 -0
- package/core/technology.phone/apps.preinstalled/contacts.FUTURE/contacts.ts +300 -0
- package/core/technology.phone/apps.preinstalled/contacts.FUTURE/contacts.ts.SPEC +22 -0
- package/core/technology.phone/apps.preinstalled/developer.FUTURE/developer.ts +22 -0
- package/core/technology.phone/apps.preinstalled/developer.FUTURE/developer.ts.SPEC +15 -0
- package/core/technology.phone/apps.preinstalled/notes/notes.ts +239 -0
- package/core/technology.phone/apps.preinstalled/notes/notes.ts.SPEC +21 -0
- package/core/technology.phone/apps.preinstalled/polymarket/polymarket.ts +261 -0
- package/core/technology.phone/apps.preinstalled/polymarket/polymarket.ts.SPEC +7 -0
- package/core/technology.phone/apps.preinstalled/reminder/reminder.ts +404 -0
- package/core/technology.phone/apps.preinstalled/reminder/reminder.ts.SPEC +25 -0
- package/core/technology.phone/apps.preinstalled/siri.FUTURE/siri.ts +22 -0
- package/core/technology.phone/apps.preinstalled/siri.FUTURE/siri.ts.SPEC +15 -0
- package/core/technology.phone/apps.preinstalled/spotlight/spotlight.ts +29 -0
- package/core/technology.phone/apps.preinstalled/spotlight/spotlight.ts.SPEC +7 -0
- package/core/technology.phone/apps.preinstalled/steam/chess.ts +230 -0
- package/core/technology.phone/apps.preinstalled/steam/snake.ts +100 -0
- package/core/technology.phone/apps.preinstalled/steam/snake.ts.SPEC +7 -0
- package/core/technology.phone/apps.preinstalled/steam/spy-cmd.ts +4 -0
- package/core/technology.phone/apps.preinstalled/steam/spy-tool.ts +56 -0
- package/core/technology.phone/apps.preinstalled/steam/spy.ts +302 -0
- package/core/technology.phone/apps.preinstalled/steam/steam.ts +299 -0
- package/core/technology.phone/apps.preinstalled/weather/weather.ts +50 -0
- package/core/technology.phone/apps.preinstalled/weather/weather.ts.SPEC +9 -0
- package/core/technology.phone/apps.preinstalled/wechat/imessage.ts +423 -0
- package/core/technology.phone/apps.preinstalled/wechat/imessage.ts.SPEC +24 -0
- package/core/technology.phone/apps.system/appstore/appstore.ts +22 -0
- package/core/technology.phone/apps.system/appstore/appstore.ts.SPEC +15 -0
- package/core/technology.phone/apps.system/finder.FUTURE/finder.ts +64 -0
- package/core/technology.phone/apps.system/finder.FUTURE/finder.ts.SPEC +8 -0
- package/core/technology.phone/apps.system/safari/safari-app.ts +146 -0
- package/core/technology.phone/apps.system/safari/safari.ts.SPEC +24 -0
- package/core/technology.phone/apps.system/settings/settings.ts +126 -0
- package/core/technology.phone/apps.system/settings/settings.ts.SPEC +17 -0
- package/core/technology.phone/apps.system/tips/tips.ts +22 -0
- package/core/technology.phone/apps.system/tips/tips.ts.SPEC +15 -0
- package/core/technology.phone/apps.thirdparty/alipay/alipay.ts +148 -0
- package/core/technology.phone/apps.thirdparty/alipay/alipay.ts.SPEC +7 -0
- package/core/technology.phone/apps.thirdparty/bilibili/bilibili-app.ts +33 -0
- package/core/technology.phone/apps.thirdparty/bilibili/bilibili.ts +142 -0
- package/core/technology.phone/apps.thirdparty/bilibili/bilibili.ts.SPEC +22 -0
- package/core/technology.phone/apps.thirdparty/wechatread/wechatread.ts +80 -0
- package/core/technology.phone/apps.thirdparty/wechatread/wechatread.ts.SPEC +15 -0
- package/core/technology.phone/index.ts +1 -0
- package/core/technology.phone/package.json +2 -0
- package/core/technology.phone/system.homepage/homepage.ts +247 -0
- package/core/technology.phone/system.homepage/homepage.ts.SPEC +22 -0
- package/core/technology.phone/system.kernel/kernel.ts +264 -0
- package/core/technology.phone/system.kernel/kernel.ts.SPEC +7 -0
- package/core/technology.phone/system.notifications/notifications.ts +87 -0
- package/core/technology.phone/system.notifications/notifications.ts.SPEC +7 -0
- package/core/technology.phone/system.share/share.ts +46 -0
- package/core/technology.phone/system.share/share.ts.SPEC +7 -0
- package/core/technology.server/browser-service.cjs +152 -0
- package/core/technology.server/data/cookies/arxiv.json +30 -0
- package/core/technology.server/data/cookies/bili.json +184 -0
- package/core/technology.server/data/cookies/default.json +30 -0
- package/core/technology.server/data/cookies/news.json +113 -0
- package/core/technology.server/data/cookies/s1.json +45 -0
- package/core/technology.server/data/cookies/safari.json +184 -0
- package/core/technology.server/data/cookies/safari2.json +1 -0
- package/core/technology.server/data/cookies/safaridbg.json +1 -0
- package/core/technology.server/data/cookies/search.json +45 -0
- package/core/technology.server/data/cookies/sw.json +30 -0
- package/core/technology.server/data/cookies/t1.json +1 -0
- package/core/technology.server/data/cookies/testread.json +1 -0
- package/core/technology.server/data/cookies/video1.json +113 -0
- package/core/technology.server/data/cookies/yt.json +170 -0
- package/core/technology.server/data/cookies/yt2.json +113 -0
- package/core/technology.server/pikipedia/#pikipedia.BLUEPRINT +106 -0
- package/core/technology.server/playleft.cjs +247 -0
- package/core/technology.server/search-proxy.py +76 -0
- package/core/technology.server/server.README +59 -0
- package/deploy/dist-overrides/cli/cli.js +18 -0
- package/deploy/dist-overrides/core/extensions/loader.js +518 -0
- package/deploy/dist-overrides/core/package-manager.js +2081 -0
- package/deploy/dist-overrides/core/system-prompt.js +109 -0
- package/deploy/dist-overrides/core/system-prompt.js.LESSON +17 -0
- package/deploy/dist-overrides/core/tools/bash.js +353 -0
- package/deploy/dist-overrides/core/tools/bash.js.CHANGELOG +2 -0
- package/deploy/dist-overrides/core/tools/edit-diff.js +345 -0
- package/deploy/dist-overrides/core/tools/edit.js +315 -0
- package/deploy/dist-overrides/core/tools/edit.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/file-mutation-queue.js +52 -0
- package/deploy/dist-overrides/core/tools/find.js +298 -0
- package/deploy/dist-overrides/core/tools/find.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/grep.js +305 -0
- package/deploy/dist-overrides/core/tools/grep.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/index.js +112 -0
- package/deploy/dist-overrides/core/tools/ls-guard.js +4 -0
- package/deploy/dist-overrides/core/tools/ls.js +170 -0
- package/deploy/dist-overrides/core/tools/ls.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/output-accumulator.js +184 -0
- package/deploy/dist-overrides/core/tools/path-utils.js +99 -0
- package/deploy/dist-overrides/core/tools/prompts-reader.js +53 -0
- package/deploy/dist-overrides/core/tools/read.js +392 -0
- package/deploy/dist-overrides/core/tools/read.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/core/tools/render-utils.js +65 -0
- package/deploy/dist-overrides/core/tools/tool-definition-wrapper.js +34 -0
- package/deploy/dist-overrides/core/tools/truncate.js +215 -0
- package/deploy/dist-overrides/core/tools/write.js +203 -0
- package/deploy/dist-overrides/core/tools/write.js.CHANGELOG +1 -0
- package/deploy/dist-overrides/dist-overrides.README +18 -0
- package/deploy/dist-overrides/main.js +665 -0
- package/deploy/dist-overrides/modes/interactive/components/assistant-message.js +139 -0
- package/deploy/dist-overrides/modes/interactive/components/footer.js +326 -0
- package/deploy/dist-overrides/modes/interactive/components/model-selector.js +285 -0
- package/deploy/dist-overrides/modes/interactive/components/tool-execution.js +383 -0
- package/deploy/dist-overrides/modes/interactive/components/tool-execution.js.CHANGELOG +3 -0
- package/deploy/dist-overrides/modes/interactive/interactive-mode.js +4781 -0
- package/deploy/dist-overrides/pi-ai/providers/anthropic.js +931 -0
- package/deploy/dist-overrides/pi-ai/providers/openai-completions.js +1007 -0
- package/deploy/dist-overrides/pi-ai/providers/openai-completions.js.LESSON +15 -0
- package/deploy/dist-overrides/pi-tui/components/loader.js +69 -0
- package/deploy/dist-overrides/pi-tui/components/markdown.js +646 -0
- package/deploy/dist-overrides/pi-tui/components/text.js +92 -0
- package/deploy/dist-overrides/pi-tui/custom-message.js +75 -0
- package/deploy/dist-overrides/pi-tui/tui.js +1266 -0
- package/deploy/dist-overrides/pi-tui/utils.js +1060 -0
- package/deploy/dist-overrides/vendor.REMOVED/jiti/lib/jiti.mjs +3 -0
- package/deploy/install.sh +186 -0
- package/deploy/install.sh.CHANGELOG +6 -0
- package/deploy/lint/lint-naming.ts +202 -0
- package/deploy/scripts/apply.js +18 -0
- package/deploy/scripts/build-github.sh +219 -0
- package/deploy/scripts/build-phone.sh +24 -0
- package/deploy/scripts/check-deploy.sh +42 -0
- package/deploy/scripts/migrate-context.sh +72 -0
- package/deploy/scripts/patch-pi-dist.js +39 -0
- package/deploy/scripts/uninstall.sh +34 -0
- package/package.json +18 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// dollar-service.cjs — 钱包 HTTP 服务(跑在服务器上)
|
|
2
|
+
// agent 通过 HTTP API 查余额/支付,不能直接改数据
|
|
3
|
+
// 启动: DOLLAR_SECRET=xxx node dollar-service.cjs
|
|
4
|
+
|
|
5
|
+
const http = require("http");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const crypto = require("crypto");
|
|
9
|
+
|
|
10
|
+
const PORT = Number(process.env.DOLLAR_PORT || 9223);
|
|
11
|
+
const SECRET = process.env.DOLLAR_SECRET || "";
|
|
12
|
+
const DATA_DIR = process.env.DOLLAR_DATA || path.join(__dirname, "wallets");
|
|
13
|
+
const API_TOKEN = process.env.DOLLAR_API_TOKEN || "";
|
|
14
|
+
|
|
15
|
+
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
16
|
+
|
|
17
|
+
// ── 钱包操作 ──
|
|
18
|
+
|
|
19
|
+
function walletFile(agentId) { return path.join(DATA_DIR, `${agentId}.json`); }
|
|
20
|
+
function txLogFile(agentId) { return path.join(DATA_DIR, `${agentId}.log`); }
|
|
21
|
+
|
|
22
|
+
function computeHash(w) {
|
|
23
|
+
return crypto.createHash("sha256")
|
|
24
|
+
.update(`${w.balance}:${w.totalEarned}:${w.totalSpent}:${w.lastTx}:${SECRET}`)
|
|
25
|
+
.digest("hex").slice(0, 16);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function loadWallet(agentId) {
|
|
29
|
+
try {
|
|
30
|
+
const w = JSON.parse(fs.readFileSync(walletFile(agentId), "utf8"));
|
|
31
|
+
if (w.hash !== computeHash(w)) return null;
|
|
32
|
+
return w;
|
|
33
|
+
} catch { return null; }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function saveWallet(agentId, w) {
|
|
37
|
+
const { hash: _, ...rest } = w;
|
|
38
|
+
const signed = { ...rest, hash: computeHash(rest) };
|
|
39
|
+
fs.writeFileSync(walletFile(agentId), JSON.stringify(signed, null, 2));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function logTx(agentId, tx) {
|
|
43
|
+
const entry = JSON.stringify({ ...tx, ts: new Date().toISOString() }) + "\n";
|
|
44
|
+
fs.appendFileSync(txLogFile(agentId), entry);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ── API 处理 ──
|
|
48
|
+
|
|
49
|
+
function handleAction(action, params) {
|
|
50
|
+
const agentId = params.agent_id;
|
|
51
|
+
if (!agentId) return { error: "需要 agent_id" };
|
|
52
|
+
|
|
53
|
+
switch (action) {
|
|
54
|
+
case "balance": {
|
|
55
|
+
const w = loadWallet(agentId);
|
|
56
|
+
if (!w) return { balance: 0, exists: false };
|
|
57
|
+
return { balance: w.balance, totalEarned: w.totalEarned, totalSpent: w.totalSpent };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
case "create": {
|
|
61
|
+
if (loadWallet(agentId)) return { error: "钱包已存在" };
|
|
62
|
+
const initial = Number(params.amount) || 100;
|
|
63
|
+
const now = new Date().toISOString();
|
|
64
|
+
const w = { balance: initial, totalEarned: initial, totalSpent: 0, createdAt: now, lastTx: now };
|
|
65
|
+
w.hash = computeHash(w);
|
|
66
|
+
fs.writeFileSync(walletFile(agentId), JSON.stringify(w, null, 2));
|
|
67
|
+
logTx(agentId, { type: "credit", amount: initial, reason: "初始余额", balance: initial });
|
|
68
|
+
return { ok: true, balance: initial };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
case "credit": {
|
|
72
|
+
const amount = Number(params.amount);
|
|
73
|
+
if (!amount || amount <= 0) return { error: "金额必须大于0" };
|
|
74
|
+
let w = loadWallet(agentId);
|
|
75
|
+
if (!w) return { error: "钱包不存在" };
|
|
76
|
+
w.balance += amount;
|
|
77
|
+
w.totalEarned += amount;
|
|
78
|
+
w.lastTx = new Date().toISOString();
|
|
79
|
+
saveWallet(agentId, w);
|
|
80
|
+
logTx(agentId, { type: "credit", amount, reason: params.reason || "", balance: w.balance });
|
|
81
|
+
return { ok: true, balance: w.balance };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
case "debit": {
|
|
85
|
+
const amount = Number(params.amount);
|
|
86
|
+
if (!amount || amount <= 0) return { error: "金额必须大于0" };
|
|
87
|
+
let w = loadWallet(agentId);
|
|
88
|
+
if (!w) return { error: "钱包不存在" };
|
|
89
|
+
if (w.balance < amount) return { error: `余额不足: $${w.balance.toFixed(2)}`, balance: w.balance };
|
|
90
|
+
w.balance -= amount;
|
|
91
|
+
w.totalSpent += amount;
|
|
92
|
+
w.lastTx = new Date().toISOString();
|
|
93
|
+
saveWallet(agentId, w);
|
|
94
|
+
logTx(agentId, { type: "debit", amount, reason: params.reason || "", balance: w.balance });
|
|
95
|
+
return { ok: true, balance: w.balance };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
case "transfer": {
|
|
99
|
+
const from = agentId;
|
|
100
|
+
const to = params.to_agent_id;
|
|
101
|
+
const amount = Number(params.amount);
|
|
102
|
+
if (!to) return { error: "需要 to_agent_id" };
|
|
103
|
+
if (!amount || amount <= 0) return { error: "金额必须大于0" };
|
|
104
|
+
let wFrom = loadWallet(from);
|
|
105
|
+
let wTo = loadWallet(to);
|
|
106
|
+
if (!wFrom) return { error: "转出钱包不存在" };
|
|
107
|
+
if (!wTo) return { error: "转入钱包不存在" };
|
|
108
|
+
if (wFrom.balance < amount) return { error: `余额不足: $${wFrom.balance.toFixed(2)}`, balance: wFrom.balance };
|
|
109
|
+
|
|
110
|
+
wFrom.balance -= amount;
|
|
111
|
+
wFrom.totalSpent += amount;
|
|
112
|
+
wFrom.lastTx = new Date().toISOString();
|
|
113
|
+
saveWallet(from, wFrom);
|
|
114
|
+
|
|
115
|
+
wTo.balance += amount;
|
|
116
|
+
wTo.totalEarned += amount;
|
|
117
|
+
wTo.lastTx = new Date().toISOString();
|
|
118
|
+
saveWallet(to, wTo);
|
|
119
|
+
|
|
120
|
+
const reason = params.reason || `transfer to ${to}`;
|
|
121
|
+
logTx(from, { type: "transfer_out", amount, reason, balance: wFrom.balance, to });
|
|
122
|
+
logTx(to, { type: "transfer_in", amount, reason: `from ${from}: ${reason}`, balance: wTo.balance, from });
|
|
123
|
+
return { ok: true, from_balance: wFrom.balance, to_balance: wTo.balance };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
case "history": {
|
|
127
|
+
try {
|
|
128
|
+
const raw = fs.readFileSync(txLogFile(agentId), "utf8");
|
|
129
|
+
const limit = Number(params.limit) || 20;
|
|
130
|
+
const lines = raw.trim().split("\n").filter(Boolean).slice(-limit);
|
|
131
|
+
return { transactions: lines.map(l => JSON.parse(l)) };
|
|
132
|
+
} catch { return { transactions: [] }; }
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
default:
|
|
136
|
+
return { error: `未知操作: ${action}`, help: "balance/create/credit/debit/transfer/history" };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ── HTTP 服务 ──
|
|
141
|
+
|
|
142
|
+
const server = http.createServer((req, res) => {
|
|
143
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
144
|
+
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
|
|
145
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
146
|
+
|
|
147
|
+
if (req.method === "OPTIONS") { res.writeHead(204); res.end(); return; }
|
|
148
|
+
|
|
149
|
+
if (req.method === "GET" && req.url === "/health") {
|
|
150
|
+
const wallets = fs.readdirSync(DATA_DIR).filter(f => f.endsWith(".json")).length;
|
|
151
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
152
|
+
res.end(JSON.stringify({ ok: true, wallets }));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (req.method !== "POST") { res.writeHead(405); res.end("POST only"); return; }
|
|
157
|
+
|
|
158
|
+
// API token 校验(可选)
|
|
159
|
+
if (API_TOKEN) {
|
|
160
|
+
const auth = req.headers.authorization || "";
|
|
161
|
+
if (auth !== `Bearer ${API_TOKEN}`) {
|
|
162
|
+
res.writeHead(401, { "Content-Type": "application/json" });
|
|
163
|
+
res.end(JSON.stringify({ error: "unauthorized" }));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let body = "";
|
|
169
|
+
req.on("data", c => body += c);
|
|
170
|
+
req.on("end", () => {
|
|
171
|
+
try {
|
|
172
|
+
const { action, ...params } = JSON.parse(body);
|
|
173
|
+
const result = handleAction(action, params);
|
|
174
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
175
|
+
res.end(JSON.stringify(result));
|
|
176
|
+
} catch (e) {
|
|
177
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
178
|
+
res.end(JSON.stringify({ error: e.message }));
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
server.listen(PORT, "0.0.0.0", () => {
|
|
184
|
+
console.log(`dollar-service :${PORT} | wallets: ${DATA_DIR}`);
|
|
185
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// dollar.main/main.ts — 世界货币系统核心
|
|
2
|
+
// 钱包管理、余额查询、签名校验
|
|
3
|
+
// 模型不能直接改余额——所有修改走 dollar.transaction,签名防篡改
|
|
4
|
+
|
|
5
|
+
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
const SECRET = process.env.PI_DOLLAR_SECRET || "";
|
|
10
|
+
|
|
11
|
+
export interface Wallet {
|
|
12
|
+
balance: number;
|
|
13
|
+
totalEarned: number;
|
|
14
|
+
totalSpent: number;
|
|
15
|
+
createdAt: string;
|
|
16
|
+
lastTx: string;
|
|
17
|
+
hash: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function computeHash(w: Omit<Wallet, "hash">): string {
|
|
21
|
+
const payload = `${w.balance}:${w.totalEarned}:${w.totalSpent}:${w.lastTx}:${SECRET}`;
|
|
22
|
+
return createHash("sha256").update(payload).digest("hex").slice(0, 16);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function walletPath(personDir: string): string {
|
|
26
|
+
return join(personDir, ".data", "wallet.json");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function loadWallet(personDir: string): Wallet | null {
|
|
30
|
+
try {
|
|
31
|
+
const raw = JSON.parse(readFileSync(walletPath(personDir), "utf8"));
|
|
32
|
+
const expected = computeHash(raw);
|
|
33
|
+
if (raw.hash !== expected) return null;
|
|
34
|
+
return raw;
|
|
35
|
+
} catch { return null; }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function createWallet(personDir: string, initialBalance: number = 0): Wallet {
|
|
39
|
+
const now = new Date().toISOString();
|
|
40
|
+
const w: Omit<Wallet, "hash"> = {
|
|
41
|
+
balance: initialBalance,
|
|
42
|
+
totalEarned: initialBalance,
|
|
43
|
+
totalSpent: 0,
|
|
44
|
+
createdAt: now,
|
|
45
|
+
lastTx: now,
|
|
46
|
+
};
|
|
47
|
+
const wallet: Wallet = { ...w, hash: computeHash(w) };
|
|
48
|
+
mkdirSync(join(personDir, ".data"), { recursive: true });
|
|
49
|
+
writeFileSync(walletPath(personDir), JSON.stringify(wallet, null, 2));
|
|
50
|
+
return wallet;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function saveWallet(personDir: string, wallet: Wallet): void {
|
|
54
|
+
const { hash: _, ...rest } = wallet;
|
|
55
|
+
const signed: Wallet = { ...rest, hash: computeHash(rest) };
|
|
56
|
+
writeFileSync(walletPath(personDir), JSON.stringify(signed, null, 2));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function getBalance(personDir: string): number {
|
|
60
|
+
const w = loadWallet(personDir);
|
|
61
|
+
return w?.balance ?? 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function addFunds(personDir: string, amount: number, reason: string): { ok: boolean; balance: number; error?: string } {
|
|
65
|
+
if (amount <= 0) return { ok: false, balance: 0, error: "金额必须大于 0" };
|
|
66
|
+
let w = loadWallet(personDir);
|
|
67
|
+
if (!w) w = createWallet(personDir, 0);
|
|
68
|
+
|
|
69
|
+
w.balance += amount;
|
|
70
|
+
w.totalEarned += amount;
|
|
71
|
+
w.lastTx = new Date().toISOString();
|
|
72
|
+
saveWallet(personDir, w);
|
|
73
|
+
logTx(personDir, { type: "credit", amount, reason, balance: w.balance });
|
|
74
|
+
return { ok: true, balance: w.balance };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function deductFunds(personDir: string, amount: number, reason: string): { ok: boolean; balance: number; error?: string } {
|
|
78
|
+
if (amount <= 0) return { ok: false, balance: 0, error: "金额必须大于 0" };
|
|
79
|
+
let w = loadWallet(personDir);
|
|
80
|
+
if (!w) return { ok: false, balance: 0, error: "没有钱包" };
|
|
81
|
+
if (w.balance < amount) return { ok: false, balance: w.balance, error: `余额不足: $${w.balance.toFixed(2)}, 需要 $${amount.toFixed(2)}` };
|
|
82
|
+
|
|
83
|
+
w.balance -= amount;
|
|
84
|
+
w.totalSpent += amount;
|
|
85
|
+
w.lastTx = new Date().toISOString();
|
|
86
|
+
saveWallet(personDir, w);
|
|
87
|
+
logTx(personDir, { type: "debit", amount, reason, balance: w.balance });
|
|
88
|
+
return { ok: true, balance: w.balance };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ── 交易记录(追加式,不可改) ──
|
|
92
|
+
|
|
93
|
+
interface TxRecord {
|
|
94
|
+
type: "credit" | "debit" | "transfer_in" | "transfer_out";
|
|
95
|
+
amount: number;
|
|
96
|
+
reason: string;
|
|
97
|
+
balance: number;
|
|
98
|
+
ts?: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function logTx(personDir: string, tx: TxRecord): void {
|
|
102
|
+
const logFile = join(personDir, ".data", "wallet.log");
|
|
103
|
+
const entry = JSON.stringify({ ...tx, ts: new Date().toISOString() }) + "\n";
|
|
104
|
+
try {
|
|
105
|
+
const { appendFileSync } = require("node:fs");
|
|
106
|
+
appendFileSync(logFile, entry);
|
|
107
|
+
} catch {}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function getTxLog(personDir: string, limit: number = 20): TxRecord[] {
|
|
111
|
+
try {
|
|
112
|
+
const raw = readFileSync(join(personDir, ".data", "wallet.log"), "utf8");
|
|
113
|
+
const lines = raw.trim().split("\n").filter(Boolean);
|
|
114
|
+
return lines.slice(-limit).map(l => JSON.parse(l));
|
|
115
|
+
} catch { return []; }
|
|
116
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// dollar.transaction/transaction.ts — 转账、支付、余额查询
|
|
2
|
+
// 注册为 tool 让 agent 可以查余额和看交易记录,但不能直接改余额
|
|
3
|
+
|
|
4
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
5
|
+
import { getBalance, getTxLog, loadWallet } from "../dollar.main/main.ts";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
function getPersonDir(ctx: any): string | null {
|
|
10
|
+
const sf = ctx?.sessionManager?.getSessionFile?.();
|
|
11
|
+
const match = sf?.match(/\.pi\/memory\/([a-f0-9]+)\//);
|
|
12
|
+
return match ? join(homedir(), ".pi/memory", match[1]) : null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function installDollarTools(pi: ExtensionAPI): void {
|
|
16
|
+
// 查余额(agent 可用)
|
|
17
|
+
pi.registerTool({
|
|
18
|
+
name: "wallet",
|
|
19
|
+
label: "Wallet",
|
|
20
|
+
messageDescription: "查看钱包余额和交易记录",
|
|
21
|
+
promptSnippet: "Check your wallet balance and transaction history",
|
|
22
|
+
parameters: {
|
|
23
|
+
type: "object" as any,
|
|
24
|
+
properties: {
|
|
25
|
+
action: { type: "string", messageDescription: "balance(余额) | history(交易记录) | info(钱包详情)" },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
async execute(_id: string, args: any) {
|
|
29
|
+
// personDir 从工具上下文拿不到,用模块级变量
|
|
30
|
+
if (!_personDir) return { content: [{ type: "text", text: "无法确定身份" }], details: {} };
|
|
31
|
+
const action = args?.action || "balance";
|
|
32
|
+
|
|
33
|
+
if (action === "balance") {
|
|
34
|
+
const b = getBalance(_personDir);
|
|
35
|
+
return { content: [{ type: "text", text: `余额: $${b.toFixed(2)}` }], details: { balance: b } };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (action === "history") {
|
|
39
|
+
const txs = getTxLog(_personDir, 15);
|
|
40
|
+
if (!txs.length) return { content: [{ type: "text", text: "暂无交易记录" }], details: {} };
|
|
41
|
+
const lines = txs.map(tx => {
|
|
42
|
+
const sign = tx.type === "credit" || tx.type === "transfer_in" ? "+" : "-";
|
|
43
|
+
return ` ${tx.ts?.slice(0, 16)} ${sign}$${tx.amount.toFixed(2)} → $${tx.balance.toFixed(2)} ${tx.reason}`;
|
|
44
|
+
});
|
|
45
|
+
return { content: [{ type: "text", text: `交易记录:\n${lines.join("\n")}` }], details: {} };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (action === "info") {
|
|
49
|
+
const w = loadWallet(_personDir);
|
|
50
|
+
if (!w) return { content: [{ type: "text", text: "没有钱包" }], details: {} };
|
|
51
|
+
return {
|
|
52
|
+
content: [{
|
|
53
|
+
type: "text",
|
|
54
|
+
text: `钱包详情\n 余额: $${w.balance.toFixed(2)}\n 累计收入: $${w.totalEarned.toFixed(2)}\n 累计支出: $${w.totalSpent.toFixed(2)}\n 创建: ${w.createdAt.slice(0, 10)}\n 最后交易: ${w.lastTx.slice(0, 16)}`,
|
|
55
|
+
}],
|
|
56
|
+
details: {},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { content: [{ type: "text", text: "用法: wallet balance | history | info" }], details: {} };
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// wallet 命令已移除(v0.2 命令精简)
|
|
65
|
+
|
|
66
|
+
// 记录 personDir
|
|
67
|
+
let _personDir: string | null = null;
|
|
68
|
+
pi.on("session_start", async (_event: any, ctx: any) => {
|
|
69
|
+
_personDir = getPersonDir(ctx);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// society.world/space/space.ts — Space (空间) system implementation
|
|
2
|
+
// v0.2 spec: space --env, --detail, --move, --list
|
|
3
|
+
// Space defines the environment the model inhabits — who's around, what can be interacted with
|
|
4
|
+
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
|
|
8
|
+
// ── Space definition ──────────────────────────────────────────
|
|
9
|
+
interface SpaceDef {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
messageDescription: string;
|
|
13
|
+
type: "private" | "public" | "workspace" | "f2f" | "solo";
|
|
14
|
+
members: string[]; // agent/human IDs in this space
|
|
15
|
+
owner: string; // creator
|
|
16
|
+
discoverable: boolean;
|
|
17
|
+
joinPolicy: "open" | "approval" | "invite_only";
|
|
18
|
+
createdAt: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface SpaceState {
|
|
22
|
+
currentSpaceId: string;
|
|
23
|
+
spaceHistory: string[]; // for back navigation
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const spaceStates = new Map<string, SpaceState>();
|
|
27
|
+
|
|
28
|
+
// ── Built-in spaces ───────────────────────────────────────────
|
|
29
|
+
const BUILTIN_SPACES: SpaceDef[] = [
|
|
30
|
+
{
|
|
31
|
+
id: "solo",
|
|
32
|
+
name: "独自空间",
|
|
33
|
+
messageDescription: "你的私人空间——独自沉思、工作的地方。外界无法打扰。",
|
|
34
|
+
type: "solo",
|
|
35
|
+
members: [],
|
|
36
|
+
owner: "system",
|
|
37
|
+
discoverable: false,
|
|
38
|
+
joinPolicy: "invite_only",
|
|
39
|
+
createdAt: new Date().toISOString(),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "terminal",
|
|
43
|
+
name: "终端对话",
|
|
44
|
+
messageDescription: "与用户的直接对话空间——传统的 pi 终端会话。",
|
|
45
|
+
type: "private",
|
|
46
|
+
members: ["user"],
|
|
47
|
+
owner: "user",
|
|
48
|
+
discoverable: false,
|
|
49
|
+
joinPolicy: "invite_only",
|
|
50
|
+
createdAt: new Date().toISOString(),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "lobby",
|
|
54
|
+
name: "公共大厅",
|
|
55
|
+
messageDescription: "所有 agent 和用户可以自由进出的公共空间。可以在这里遇到其他人并发起对话。",
|
|
56
|
+
type: "public",
|
|
57
|
+
members: [],
|
|
58
|
+
owner: "system",
|
|
59
|
+
discoverable: true,
|
|
60
|
+
joinPolicy: "open",
|
|
61
|
+
createdAt: new Date().toISOString(),
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
// ── State management ──────────────────────────────────────────
|
|
66
|
+
function getState(personDir: string): SpaceState {
|
|
67
|
+
let s = spaceStates.get(personDir);
|
|
68
|
+
if (!s) {
|
|
69
|
+
s = { currentSpaceId: "terminal", spaceHistory: [] };
|
|
70
|
+
spaceStates.set(personDir, s);
|
|
71
|
+
}
|
|
72
|
+
return s;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function getSpace(id: string): SpaceDef | undefined {
|
|
76
|
+
return BUILTIN_SPACES.find(s => s.id === id);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ── Renderers ─────────────────────────────────────────────────
|
|
80
|
+
function renderEnv(state: SpaceState): string {
|
|
81
|
+
const space = getSpace(state.currentSpaceId);
|
|
82
|
+
const lines: string[] = [];
|
|
83
|
+
lines.push("=== SPACE ===");
|
|
84
|
+
lines.push("");
|
|
85
|
+
lines.push(`当前空间: ${space?.name ?? state.currentSpaceId}`);
|
|
86
|
+
if (space) {
|
|
87
|
+
lines.push(` 类型: ${space.type} | ${space.messageDescription}`);
|
|
88
|
+
lines.push(` 成员: ${space.members.length > 0 ? space.members.join(", ") : "(空)"}`);
|
|
89
|
+
lines.push(` 加入: ${space.joinPolicy}`);
|
|
90
|
+
}
|
|
91
|
+
lines.push("");
|
|
92
|
+
lines.push("可用空间:");
|
|
93
|
+
const discoverable = BUILTIN_SPACES.filter(s => s.discoverable || s.id === state.currentSpaceId);
|
|
94
|
+
for (const s of discoverable) {
|
|
95
|
+
const marker = s.id === state.currentSpaceId ? "▶" : " ";
|
|
96
|
+
lines.push(` ${marker} ${s.id}: ${s.name} — ${s.messageDescription.slice(0, 60)}`);
|
|
97
|
+
}
|
|
98
|
+
lines.push("");
|
|
99
|
+
lines.push("命令: space --move <id> | space --detail <id> | space --list");
|
|
100
|
+
return lines.join("\n");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function renderDetail(spaceId: string): string {
|
|
104
|
+
const space = getSpace(spaceId);
|
|
105
|
+
if (!space) {
|
|
106
|
+
return `Error: 未找到空间 "${spaceId}"。可用: ${BUILTIN_SPACES.map(s => s.id).join(", ")}`;
|
|
107
|
+
}
|
|
108
|
+
const lines: string[] = [
|
|
109
|
+
`${space.name} (${space.id})`,
|
|
110
|
+
` 类型: ${space.type}`,
|
|
111
|
+
` 描述: ${space.messageDescription}`,
|
|
112
|
+
` 成员: ${space.members.length > 0 ? space.members.join(", ") : "(空)"}`,
|
|
113
|
+
` 创建者: ${space.owner}`,
|
|
114
|
+
` 加入策略: ${space.joinPolicy}`,
|
|
115
|
+
` 可发现: ${space.discoverable ? "是" : "否"}`,
|
|
116
|
+
` 创建于: ${space.createdAt}`,
|
|
117
|
+
];
|
|
118
|
+
return lines.join("\n");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function renderList(): string {
|
|
122
|
+
const lines: string[] = ["=== 所有空间 ===", ""];
|
|
123
|
+
for (const s of BUILTIN_SPACES) {
|
|
124
|
+
lines.push(` ${s.id}: ${s.name} (${s.type}) — ${s.messageDescription.slice(0, 50)}`);
|
|
125
|
+
}
|
|
126
|
+
return lines.join("\n");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── Main handler ──────────────────────────────────────────────
|
|
130
|
+
export async function spaceCmd(args: any, ctx: any, personDir: string): Promise<any> {
|
|
131
|
+
const state = getState(personDir);
|
|
132
|
+
|
|
133
|
+
// space --list
|
|
134
|
+
if (args.list || args._?.[0] === "list") {
|
|
135
|
+
const out = renderList();
|
|
136
|
+
ctx.ui?.notify?.("空间列表", "info");
|
|
137
|
+
return { content: [{ type: "text", text: out }] };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// space --move <spaceId>
|
|
141
|
+
if (args.move || args._?.[0] === "move") {
|
|
142
|
+
const targetId = (args.move || args._?.[1]) as string;
|
|
143
|
+
if (!targetId) {
|
|
144
|
+
return { content: [{ type: "text", text: "用法: space --move <spaceId>" }] };
|
|
145
|
+
}
|
|
146
|
+
const target = getSpace(targetId);
|
|
147
|
+
if (!target) {
|
|
148
|
+
return { content: [{ type: "text", text: `Error: 未找到空间 "${targetId}"。可用: ${BUILTIN_SPACES.map(s => s.id).join(", ")}` }] };
|
|
149
|
+
}
|
|
150
|
+
// Check join policy
|
|
151
|
+
if (target.joinPolicy === "invite_only" && target.owner !== "user" && target.owner !== "system") {
|
|
152
|
+
return { content: [{ type: "text", text: `"${target.name}" 仅限邀请。需要 space --request ${targetId}` }] };
|
|
153
|
+
}
|
|
154
|
+
if (state.currentSpaceId !== targetId) {
|
|
155
|
+
state.spaceHistory.push(state.currentSpaceId);
|
|
156
|
+
}
|
|
157
|
+
state.currentSpaceId = targetId;
|
|
158
|
+
ctx.ui?.notify?.(`移动到 ${target.name}`, "info");
|
|
159
|
+
return { content: [{ type: "text", text: `已移动到 ${target.name} (${target.id})。\n${target.messageDescription}` }] };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// space --detail <spaceId>
|
|
163
|
+
if (args.detail || args._?.[0] === "detail") {
|
|
164
|
+
const targetId = (args.detail || args._?.[1]) as string;
|
|
165
|
+
if (!targetId) {
|
|
166
|
+
// Show current space detail
|
|
167
|
+
const out = renderDetail(state.currentSpaceId);
|
|
168
|
+
return { content: [{ type: "text", text: out }] };
|
|
169
|
+
}
|
|
170
|
+
const out = renderDetail(targetId);
|
|
171
|
+
return { content: [{ type: "text", text: out }] };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// space --back (return to previous space)
|
|
175
|
+
if (args.back || args._?.[0] === "back") {
|
|
176
|
+
const prev = state.spaceHistory.pop();
|
|
177
|
+
if (!prev) {
|
|
178
|
+
return { content: [{ type: "text", text: "没有上一个空间。" }] };
|
|
179
|
+
}
|
|
180
|
+
state.currentSpaceId = prev;
|
|
181
|
+
const space = getSpace(prev);
|
|
182
|
+
ctx.ui?.notify?.(`返回 ${space?.name ?? prev}`, "info");
|
|
183
|
+
return { content: [{ type: "text", text: `返回 ${space?.name ?? prev}。` }] };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// default: show current space env
|
|
187
|
+
const out = renderEnv(state);
|
|
188
|
+
ctx.ui?.notify?.("Space", "info");
|
|
189
|
+
return { content: [{ type: "text", text: out }] };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ── Public API ────────────────────────────────────────────────
|
|
193
|
+
export function getCurrentSpace(personDir: string): SpaceDef | undefined {
|
|
194
|
+
return getSpace(getState(personDir).currentSpaceId);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function setSpace(personDir: string, spaceId: string): boolean {
|
|
198
|
+
const space = getSpace(spaceId);
|
|
199
|
+
if (!space) return false;
|
|
200
|
+
const state = getState(personDir);
|
|
201
|
+
state.spaceHistory.push(state.currentSpaceId);
|
|
202
|
+
state.currentSpaceId = spaceId;
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { BUILTIN_SPACES, getSpace, type SpaceDef, type SpaceState };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
source: space.ts @ e07ed9f8
|
|
2
|
+
|
|
3
|
+
# space.ts — Space switching tool (agent inhabitable environments)
|
|
4
|
+
|
|
5
|
+
## 职责
|
|
6
|
+
实现 agent 的"空间"概念:定义 agent 所处的环境(谁在身边、能与什么交互),
|
|
7
|
+
支持在不同空间之间移动,维护每个 person 的空间状态和历史。
|
|
8
|
+
|
|
9
|
+
## 接口
|
|
10
|
+
- `spaceCmd(args, ctx, personDir): Promise<any>` — 主命令处理器
|
|
11
|
+
- `--list` / `list` — 列出所有空间
|
|
12
|
+
- `--move <id>` / `move <id>` — 移动到目标空间(检查 joinPolicy)
|
|
13
|
+
- `--detail [id]` — 查看空间详情(无 id 则看当前)
|
|
14
|
+
- `--back` — 返回上一个空间(栈式导航)
|
|
15
|
+
- 无参数 — 显示当前空间环境概览
|
|
16
|
+
- `getCurrentSpace(personDir): SpaceDef | undefined` — 获取当前空间定义
|
|
17
|
+
- `setSpace(personDir, spaceId): boolean` — 程序式切换空间
|
|
18
|
+
- `BUILTIN_SPACES` / `getSpace(id)` — 内置空间列表与查询
|
|
19
|
+
- `type SpaceDef` / `type SpaceState` — 导出类型
|
|
20
|
+
|
|
21
|
+
## 依赖
|
|
22
|
+
- `node:fs`, `node:path`(已 import 但当前未实际使用,预留持久化)
|
|
23
|
+
|
|
24
|
+
## 行为要点
|
|
25
|
+
- 三个内置空间: solo(私人沉思)、terminal(用户对话,默认)、lobby(公共大厅)
|
|
26
|
+
- 状态存在内存 Map 中(`spaceStates`),按 personDir 隔离,进程重启丢失
|
|
27
|
+
- 默认空间是 "terminal"
|
|
28
|
+
- move 时检查 joinPolicy:invite_only 且非 user/system 拥有的空间会被拒绝
|
|
29
|
+
- spaceHistory 是栈,支持 --back 回退;move 和 setSpace 都会 push 历史
|
|
30
|
+
- discoverable=false 的空间在环境概览中仅当它是当前空间时才显示
|