gipity 1.0.355 → 1.0.365
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/dist/capture/sources/claude-code.js +76 -11
- package/dist/commands/add.js +44 -27
- package/dist/commands/generate.js +16 -13
- package/dist/commands/page-eval.js +42 -3
- package/dist/commands/page-inspect.js +32 -4
- package/dist/commands/page-screenshot.js +34 -23
- package/dist/commands/page-test.js +86 -0
- package/dist/commands/page.js +5 -3
- package/dist/commands/service.js +56 -0
- package/dist/commands/skill.js +2 -1
- package/dist/commands/text.js +148 -0
- package/dist/commands/workflow.js +10 -14
- package/dist/config.js +8 -1
- package/dist/help-skills.js +1 -0
- package/dist/helpers/output.js +7 -1
- package/dist/helpers/text-analysis.js +200 -0
- package/dist/hooks/capture-runner.js +32 -8
- package/dist/index.js +31 -2
- package/dist/knowledge.js +13 -3
- package/dist/relay/daemon.js +11 -1
- package/dist/relay/stream-json.js +45 -8
- package/dist/setup.js +18 -4
- package/dist/sync.js +14 -2
- package/package.json +8 -7
- package/dist/__tests__/adopt-cwd.test.d.ts +0 -1
- package/dist/__tests__/adopt-cwd.test.js +0 -176
- package/dist/__tests__/adopt-cwd.test.js.map +0 -1
- package/dist/__tests__/capture-transcript.test.d.ts +0 -1
- package/dist/__tests__/capture-transcript.test.js +0 -92
- package/dist/__tests__/capture-transcript.test.js.map +0 -1
- package/dist/__tests__/claude-noninteractive.test.d.ts +0 -1
- package/dist/__tests__/claude-noninteractive.test.js +0 -92
- package/dist/__tests__/claude-noninteractive.test.js.map +0 -1
- package/dist/__tests__/claude-trust.test.d.ts +0 -1
- package/dist/__tests__/claude-trust.test.js +0 -71
- package/dist/__tests__/claude-trust.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-add.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-add.test.js +0 -45
- package/dist/__tests__/cli-cmd-add.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-agent.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-agent.test.js +0 -76
- package/dist/__tests__/cli-cmd-agent.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-approval.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-approval.test.js +0 -47
- package/dist/__tests__/cli-cmd-approval.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-audit.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-audit.test.js +0 -33
- package/dist/__tests__/cli-cmd-audit.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-chat.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-chat.test.js +0 -94
- package/dist/__tests__/cli-cmd-chat.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-credits.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-credits.test.js +0 -66
- package/dist/__tests__/cli-cmd-credits.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-db.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-db.test.js +0 -95
- package/dist/__tests__/cli-cmd-db.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-deploy.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-deploy.test.js +0 -53
- package/dist/__tests__/cli-cmd-deploy.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-domain.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-domain.test.js +0 -73
- package/dist/__tests__/cli-cmd-domain.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-email.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-email.test.js +0 -31
- package/dist/__tests__/cli-cmd-email.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-file.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-file.test.js +0 -86
- package/dist/__tests__/cli-cmd-file.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-fn.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-fn.test.js +0 -50
- package/dist/__tests__/cli-cmd-fn.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-generate.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-generate.test.js +0 -46
- package/dist/__tests__/cli-cmd-generate.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-gmail.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-gmail.test.js +0 -49
- package/dist/__tests__/cli-cmd-gmail.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-info.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-info.test.js +0 -52
- package/dist/__tests__/cli-cmd-info.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-init.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-init.test.js +0 -76
- package/dist/__tests__/cli-cmd-init.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-job.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-job.test.js +0 -204
- package/dist/__tests__/cli-cmd-job.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-location.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-location.test.js +0 -58
- package/dist/__tests__/cli-cmd-location.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-login.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-login.test.js +0 -41
- package/dist/__tests__/cli-cmd-login.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-logout.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-logout.test.js +0 -20
- package/dist/__tests__/cli-cmd-logout.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-logs.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-logs.test.js +0 -40
- package/dist/__tests__/cli-cmd-logs.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-memory.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-memory.test.js +0 -58
- package/dist/__tests__/cli-cmd-memory.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-page-inspect.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-page-inspect.test.js +0 -47
- package/dist/__tests__/cli-cmd-page-inspect.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-page.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-page.test.js +0 -90
- package/dist/__tests__/cli-cmd-page.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-plan.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-plan.test.js +0 -81
- package/dist/__tests__/cli-cmd-plan.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-project.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-project.test.js +0 -61
- package/dist/__tests__/cli-cmd-project.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-rbac.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-rbac.test.js +0 -39
- package/dist/__tests__/cli-cmd-rbac.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-realtime.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-realtime.test.js +0 -51
- package/dist/__tests__/cli-cmd-realtime.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-records.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-records.test.js +0 -67
- package/dist/__tests__/cli-cmd-records.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-relay.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-relay.test.js +0 -100
- package/dist/__tests__/cli-cmd-relay.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-sandbox.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-sandbox.test.js +0 -46
- package/dist/__tests__/cli-cmd-sandbox.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-scaffold.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-scaffold.test.js +0 -30
- package/dist/__tests__/cli-cmd-scaffold.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-skill.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-skill.test.js +0 -40
- package/dist/__tests__/cli-cmd-skill.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-test.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-test.test.js +0 -58
- package/dist/__tests__/cli-cmd-test.test.js.map +0 -1
- package/dist/__tests__/cli-cmd-workflow.test.d.ts +0 -1
- package/dist/__tests__/cli-cmd-workflow.test.js +0 -84
- package/dist/__tests__/cli-cmd-workflow.test.js.map +0 -1
- package/dist/__tests__/cli-e2e-live.test.d.ts +0 -1
- package/dist/__tests__/cli-e2e-live.test.js +0 -144
- package/dist/__tests__/cli-e2e-live.test.js.map +0 -1
- package/dist/__tests__/cli-smoke.test.d.ts +0 -1
- package/dist/__tests__/cli-smoke.test.js +0 -69
- package/dist/__tests__/cli-smoke.test.js.map +0 -1
- package/dist/__tests__/config.test.d.ts +0 -1
- package/dist/__tests__/config.test.js +0 -95
- package/dist/__tests__/config.test.js.map +0 -1
- package/dist/__tests__/flag-aliases.test.d.ts +0 -1
- package/dist/__tests__/flag-aliases.test.js +0 -53
- package/dist/__tests__/flag-aliases.test.js.map +0 -1
- package/dist/__tests__/helpers/mock-server.d.ts +0 -52
- package/dist/__tests__/helpers/mock-server.js +0 -86
- package/dist/__tests__/helpers/mock-server.js.map +0 -1
- package/dist/__tests__/helpers/spawn-cli.d.ts +0 -30
- package/dist/__tests__/helpers/spawn-cli.js +0 -72
- package/dist/__tests__/helpers/spawn-cli.js.map +0 -1
- package/dist/__tests__/helpers/test-home.d.ts +0 -22
- package/dist/__tests__/helpers/test-home.js +0 -35
- package/dist/__tests__/helpers/test-home.js.map +0 -1
- package/dist/__tests__/hook-capture.test.d.ts +0 -1
- package/dist/__tests__/hook-capture.test.js +0 -65
- package/dist/__tests__/hook-capture.test.js.map +0 -1
- package/dist/__tests__/prompts.test.d.ts +0 -1
- package/dist/__tests__/prompts.test.js +0 -129
- package/dist/__tests__/prompts.test.js.map +0 -1
- package/dist/__tests__/push-cas.test.d.ts +0 -1
- package/dist/__tests__/push-cas.test.js +0 -133
- package/dist/__tests__/push-cas.test.js.map +0 -1
- package/dist/__tests__/relay-bridge-abort.test.d.ts +0 -1
- package/dist/__tests__/relay-bridge-abort.test.js +0 -65
- package/dist/__tests__/relay-bridge-abort.test.js.map +0 -1
- package/dist/__tests__/relay-daemon.test.d.ts +0 -1
- package/dist/__tests__/relay-daemon.test.js +0 -232
- package/dist/__tests__/relay-daemon.test.js.map +0 -1
- package/dist/__tests__/relay-ingest-contract.test.d.ts +0 -1
- package/dist/__tests__/relay-ingest-contract.test.js +0 -76
- package/dist/__tests__/relay-ingest-contract.test.js.map +0 -1
- package/dist/__tests__/relay-installers.test.d.ts +0 -1
- package/dist/__tests__/relay-installers.test.js +0 -95
- package/dist/__tests__/relay-installers.test.js.map +0 -1
- package/dist/__tests__/relay-machine-id.test.d.ts +0 -1
- package/dist/__tests__/relay-machine-id.test.js +0 -41
- package/dist/__tests__/relay-machine-id.test.js.map +0 -1
- package/dist/__tests__/relay-pair.test.d.ts +0 -1
- package/dist/__tests__/relay-pair.test.js.map +0 -1
- package/dist/__tests__/relay-redact.test.d.ts +0 -1
- package/dist/__tests__/relay-redact.test.js +0 -78
- package/dist/__tests__/relay-redact.test.js.map +0 -1
- package/dist/__tests__/relay-state.test.d.ts +0 -1
- package/dist/__tests__/relay-state.test.js +0 -85
- package/dist/__tests__/relay-state.test.js.map +0 -1
- package/dist/__tests__/setup-skills-block.test.d.ts +0 -1
- package/dist/__tests__/setup-skills-block.test.js +0 -65
- package/dist/__tests__/setup-skills-block.test.js.map +0 -1
- package/dist/__tests__/stream-json.test.d.ts +0 -1
- package/dist/__tests__/stream-json.test.js +0 -186
- package/dist/__tests__/stream-json.test.js.map +0 -1
- package/dist/__tests__/sync-apply.test.d.ts +0 -1
- package/dist/__tests__/sync-apply.test.js +0 -457
- package/dist/__tests__/sync-apply.test.js.map +0 -1
- package/dist/__tests__/sync-lock.test.d.ts +0 -1
- package/dist/__tests__/sync-lock.test.js +0 -105
- package/dist/__tests__/sync-lock.test.js.map +0 -1
- package/dist/__tests__/sync.test.d.ts +0 -1
- package/dist/__tests__/sync.test.js +0 -160
- package/dist/__tests__/sync.test.js.map +0 -1
- package/dist/__tests__/template-vars.test.d.ts +0 -1
- package/dist/__tests__/template-vars.test.js +0 -119
- package/dist/__tests__/template-vars.test.js.map +0 -1
- package/dist/__tests__/updater.test.d.ts +0 -1
- package/dist/__tests__/updater.test.js +0 -95
- package/dist/__tests__/updater.test.js.map +0 -1
- package/dist/__tests__/upload.test.d.ts +0 -1
- package/dist/__tests__/upload.test.js +0 -92
- package/dist/__tests__/upload.test.js.map +0 -1
- package/dist/__tests__/utils.test.d.ts +0 -1
- package/dist/__tests__/utils.test.js +0 -69
- package/dist/__tests__/utils.test.js.map +0 -1
- package/dist/adopt-cwd.d.ts +0 -69
- package/dist/adopt-cwd.js.map +0 -1
- package/dist/api.d.ts +0 -41
- package/dist/api.js.map +0 -1
- package/dist/auth.d.ts +0 -17
- package/dist/auth.js.map +0 -1
- package/dist/banner.d.ts +0 -6
- package/dist/banner.js.map +0 -1
- package/dist/capture/sources/claude-code.d.ts +0 -78
- package/dist/capture/sources/claude-code.js.map +0 -1
- package/dist/coding-guidelines.d.ts +0 -9
- package/dist/coding-guidelines.js.map +0 -1
- package/dist/colors.d.ts +0 -22
- package/dist/colors.js.map +0 -1
- package/dist/commands/add.d.ts +0 -2
- package/dist/commands/add.js.map +0 -1
- package/dist/commands/agent.d.ts +0 -2
- package/dist/commands/agent.js.map +0 -1
- package/dist/commands/api.d.ts +0 -1
- package/dist/commands/api.js.map +0 -1
- package/dist/commands/approval.d.ts +0 -2
- package/dist/commands/approval.js.map +0 -1
- package/dist/commands/audit.d.ts +0 -2
- package/dist/commands/audit.js.map +0 -1
- package/dist/commands/browser.d.ts +0 -2
- package/dist/commands/browser.js.map +0 -1
- package/dist/commands/chat.d.ts +0 -2
- package/dist/commands/chat.js.map +0 -1
- package/dist/commands/checkpoint.d.ts +0 -2
- package/dist/commands/checkpoint.js.map +0 -1
- package/dist/commands/claude.d.ts +0 -16
- package/dist/commands/claude.js.map +0 -1
- package/dist/commands/credits.d.ts +0 -2
- package/dist/commands/credits.js.map +0 -1
- package/dist/commands/db.d.ts +0 -2
- package/dist/commands/db.js.map +0 -1
- package/dist/commands/deploy.d.ts +0 -2
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/doctor.d.ts +0 -2
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/domain.d.ts +0 -2
- package/dist/commands/domain.js.map +0 -1
- package/dist/commands/email.d.ts +0 -2
- package/dist/commands/email.js.map +0 -1
- package/dist/commands/file.d.ts +0 -2
- package/dist/commands/file.js.map +0 -1
- package/dist/commands/fn.d.ts +0 -2
- package/dist/commands/fn.js.map +0 -1
- package/dist/commands/generate.d.ts +0 -2
- package/dist/commands/generate.js.map +0 -1
- package/dist/commands/gmail.d.ts +0 -2
- package/dist/commands/gmail.js.map +0 -1
- package/dist/commands/hook-capture.d.ts +0 -15
- package/dist/commands/hook-capture.js.map +0 -1
- package/dist/commands/init.d.ts +0 -2
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/job.d.ts +0 -2
- package/dist/commands/job.js.map +0 -1
- package/dist/commands/location.d.ts +0 -9
- package/dist/commands/location.js.map +0 -1
- package/dist/commands/login.d.ts +0 -2
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts +0 -2
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/logs.d.ts +0 -2
- package/dist/commands/logs.js.map +0 -1
- package/dist/commands/memory.d.ts +0 -2
- package/dist/commands/memory.js.map +0 -1
- package/dist/commands/page-eval.d.ts +0 -2
- package/dist/commands/page-eval.js.map +0 -1
- package/dist/commands/page-inspect.d.ts +0 -2
- package/dist/commands/page-inspect.js.map +0 -1
- package/dist/commands/page-screenshot.d.ts +0 -2
- package/dist/commands/page-screenshot.js.map +0 -1
- package/dist/commands/page.d.ts +0 -2
- package/dist/commands/page.js.map +0 -1
- package/dist/commands/plan.d.ts +0 -2
- package/dist/commands/plan.js.map +0 -1
- package/dist/commands/project.d.ts +0 -2
- package/dist/commands/project.js.map +0 -1
- package/dist/commands/push.d.ts +0 -2
- package/dist/commands/push.js.map +0 -1
- package/dist/commands/rbac.d.ts +0 -2
- package/dist/commands/rbac.js.map +0 -1
- package/dist/commands/realtime.d.ts +0 -2
- package/dist/commands/realtime.js.map +0 -1
- package/dist/commands/records.d.ts +0 -2
- package/dist/commands/records.js.map +0 -1
- package/dist/commands/relay-install.d.ts +0 -11
- package/dist/commands/relay-install.js.map +0 -1
- package/dist/commands/relay.d.ts +0 -9
- package/dist/commands/relay.js.map +0 -1
- package/dist/commands/sandbox.d.ts +0 -2
- package/dist/commands/sandbox.js.map +0 -1
- package/dist/commands/scaffold.d.ts +0 -2
- package/dist/commands/scaffold.js.map +0 -1
- package/dist/commands/skill.d.ts +0 -2
- package/dist/commands/skill.js.map +0 -1
- package/dist/commands/skills.d.ts +0 -2
- package/dist/commands/skills.js.map +0 -1
- package/dist/commands/start-cc.d.ts +0 -2
- package/dist/commands/start-cc.js.map +0 -1
- package/dist/commands/status.d.ts +0 -2
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/sync.d.ts +0 -2
- package/dist/commands/sync.js.map +0 -1
- package/dist/commands/test.d.ts +0 -2
- package/dist/commands/test.js.map +0 -1
- package/dist/commands/uninstall.d.ts +0 -10
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/commands/update.d.ts +0 -2
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/upload.d.ts +0 -2
- package/dist/commands/upload.js.map +0 -1
- package/dist/commands/workflow.d.ts +0 -2
- package/dist/commands/workflow.js.map +0 -1
- package/dist/config.d.ts +0 -39
- package/dist/config.js.map +0 -1
- package/dist/flag-aliases.d.ts +0 -17
- package/dist/flag-aliases.js.map +0 -1
- package/dist/gip3dw-guide.d.ts +0 -7
- package/dist/gip3dw-guide.js.map +0 -1
- package/dist/gipcc.d.ts +0 -2
- package/dist/gipcc.js.map +0 -1
- package/dist/gipccd.d.ts +0 -2
- package/dist/gipccd.js.map +0 -1
- package/dist/help-skills.d.ts +0 -7
- package/dist/help-skills.js.map +0 -1
- package/dist/helpers/command.d.ts +0 -12
- package/dist/helpers/command.js.map +0 -1
- package/dist/helpers/index.d.ts +0 -6
- package/dist/helpers/index.js.map +0 -1
- package/dist/helpers/output.d.ts +0 -22
- package/dist/helpers/output.js.map +0 -1
- package/dist/helpers/sync.d.ts +0 -13
- package/dist/helpers/sync.js.map +0 -1
- package/dist/hooks/capture-runner.d.ts +0 -24
- package/dist/hooks/capture-runner.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js.map +0 -1
- package/dist/knowledge.d.ts +0 -11
- package/dist/knowledge.js.map +0 -1
- package/dist/platform-overview.d.ts +0 -9
- package/dist/platform-overview.js.map +0 -1
- package/dist/project-setup.d.ts +0 -29
- package/dist/project-setup.js.map +0 -1
- package/dist/prompts.d.ts +0 -80
- package/dist/prompts.js.map +0 -1
- package/dist/provider-docs.d.ts +0 -27
- package/dist/provider-docs.js.map +0 -1
- package/dist/relay/daemon.d.ts +0 -47
- package/dist/relay/daemon.js.map +0 -1
- package/dist/relay/device-http.d.ts +0 -9
- package/dist/relay/device-http.js.map +0 -1
- package/dist/relay/installers.d.ts +0 -24
- package/dist/relay/installers.js.map +0 -1
- package/dist/relay/machine-id.d.ts +0 -2
- package/dist/relay/machine-id.js.map +0 -1
- package/dist/relay/onboarding.d.ts +0 -8
- package/dist/relay/onboarding.js.map +0 -1
- package/dist/relay/paths.d.ts +0 -5
- package/dist/relay/paths.js.map +0 -1
- package/dist/relay/redact.d.ts +0 -34
- package/dist/relay/redact.js.map +0 -1
- package/dist/relay/state.d.ts +0 -39
- package/dist/relay/state.js.map +0 -1
- package/dist/relay/stream-json.d.ts +0 -105
- package/dist/relay/stream-json.js.map +0 -1
- package/dist/relay/transcripts.d.ts +0 -60
- package/dist/relay/transcripts.js.map +0 -1
- package/dist/setup.d.ts +0 -101
- package/dist/setup.js.map +0 -1
- package/dist/sync.d.ts +0 -74
- package/dist/sync.js.map +0 -1
- package/dist/template-vars.d.ts +0 -32
- package/dist/template-vars.js.map +0 -1
- package/dist/updater/bootstrap.d.ts +0 -13
- package/dist/updater/bootstrap.js.map +0 -1
- package/dist/updater/check.d.ts +0 -12
- package/dist/updater/check.js.map +0 -1
- package/dist/updater/shim.d.ts +0 -2
- package/dist/updater/shim.js.map +0 -1
- package/dist/updater/state.d.ts +0 -24
- package/dist/updater/state.js.map +0 -1
- package/dist/upload.d.ts +0 -40
- package/dist/upload.js.map +0 -1
- package/dist/utils.d.ts +0 -39
- package/dist/utils.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Internal hook runner - invoked by Claude Code's lifecycle hooks
|
|
4
|
-
* (SessionStart, Stop, SubagentStop, SessionEnd
|
|
5
|
-
*
|
|
6
|
-
* display it read-only.
|
|
4
|
+
* (SessionStart, Stop, SubagentStop, SessionEnd, and a throttled
|
|
5
|
+
* PostToolUse for mid-run flushing) to mirror a terminal `gipity claude`
|
|
6
|
+
* session into the Gipity server so the web CLI can display it read-only.
|
|
7
7
|
*
|
|
8
8
|
* Not a user-facing `gipity` subcommand by design: users never invoke
|
|
9
9
|
* this directly. `setupClaudeHooks` wires up hook entries that call
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Usage:
|
|
13
13
|
* node capture-runner.js <source> <event>
|
|
14
14
|
* source: 'claude-code' (today) | future: 'codex', …
|
|
15
|
-
* event: 'session-start' | 'stop' | 'subagent-stop' | 'session-end'
|
|
15
|
+
* event: 'session-start' | 'stop' | 'subagent-stop' | 'session-end' | 'post-tool-use'
|
|
16
16
|
*
|
|
17
17
|
* Graceful no-ops (exit 0 silently):
|
|
18
18
|
* - GIPITY_CONVERSATION_GUID env var unset (hook fired from a bare
|
|
@@ -29,6 +29,13 @@ import { deviceFetch } from '../relay/device-http.js';
|
|
|
29
29
|
import { parseTranscript, } from '../capture/sources/claude-code.js';
|
|
30
30
|
const CAPTURE_DIR = join(homedir(), '.gipity', 'capture-state');
|
|
31
31
|
const INGEST_BATCH_MAX = 100; // server caps at 200; stay comfortably under
|
|
32
|
+
// PostToolUse fires after every tool call. We flush on it so a session that is
|
|
33
|
+
// killed/crashes mid-run (e.g. a long headless `gipity claude -p` build that
|
|
34
|
+
// hits a timeout) still has its transcript in the DB - Stop/SessionEnd only
|
|
35
|
+
// fire on a CLEAN exit, so without this an interrupted run loses EVERYTHING.
|
|
36
|
+
// Throttled to one flush per this interval to bound the cost of re-scanning a
|
|
37
|
+
// growing transcript on every tool call; a kill then loses at most this much tail.
|
|
38
|
+
const POST_TOOL_FLUSH_MS = 10_000;
|
|
32
39
|
function statePath(convGuid) {
|
|
33
40
|
return join(CAPTURE_DIR, `${convGuid}.json`);
|
|
34
41
|
}
|
|
@@ -42,7 +49,10 @@ function readState(convGuid) {
|
|
|
42
49
|
try {
|
|
43
50
|
const raw = readFileSync(p, 'utf-8');
|
|
44
51
|
const parsed = JSON.parse(raw);
|
|
45
|
-
return {
|
|
52
|
+
return {
|
|
53
|
+
last_uuid: typeof parsed.last_uuid === 'string' ? parsed.last_uuid : null,
|
|
54
|
+
last_flush_ms: typeof parsed.last_flush_ms === 'number' ? parsed.last_flush_ms : undefined,
|
|
55
|
+
};
|
|
46
56
|
}
|
|
47
57
|
catch {
|
|
48
58
|
return null;
|
|
@@ -143,10 +153,17 @@ async function handleSessionStart(convGuid, hook) {
|
|
|
143
153
|
}];
|
|
144
154
|
await postEntries(convGuid, entries);
|
|
145
155
|
}
|
|
146
|
-
async function handleStopFamily(convGuid, hook, isSubagent) {
|
|
156
|
+
async function handleStopFamily(convGuid, hook, isSubagent, minIntervalMs = 0) {
|
|
147
157
|
void isSubagent;
|
|
148
158
|
if (!hook.transcript_path || !existsSync(hook.transcript_path))
|
|
149
159
|
return;
|
|
160
|
+
// Throttle high-frequency callers (PostToolUse). Stop/SessionEnd pass
|
|
161
|
+
// minIntervalMs=0 so they always flush in full on a clean exit.
|
|
162
|
+
if (minIntervalMs > 0) {
|
|
163
|
+
const prev = readState(convGuid);
|
|
164
|
+
if (prev?.last_flush_ms && Date.now() - prev.last_flush_ms < minIntervalMs)
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
150
167
|
const release = acquireLock(convGuid);
|
|
151
168
|
if (!release)
|
|
152
169
|
return; // another hook instance is already flushing; it'll catch our lines
|
|
@@ -160,8 +177,10 @@ async function handleStopFamily(convGuid, hook, isSubagent) {
|
|
|
160
177
|
result = parseTranscript(content, null);
|
|
161
178
|
}
|
|
162
179
|
const ok = await postEntries(convGuid, result.entries);
|
|
163
|
-
if (ok
|
|
164
|
-
|
|
180
|
+
if (ok) {
|
|
181
|
+
// Stamp the flush time even when no new lines landed, so the throttle
|
|
182
|
+
// above measures from the last attempt. Keep the watermark if unchanged.
|
|
183
|
+
writeState(convGuid, { last_uuid: result.lastUuid ?? state.last_uuid, last_flush_ms: Date.now() });
|
|
165
184
|
}
|
|
166
185
|
}
|
|
167
186
|
finally {
|
|
@@ -218,6 +237,11 @@ async function main() {
|
|
|
218
237
|
case 'subagent-stop':
|
|
219
238
|
await handleStopFamily(convGuid, hook, true);
|
|
220
239
|
break;
|
|
240
|
+
case 'post-tool-use':
|
|
241
|
+
// Incremental mid-run flush so an interrupted session keeps its
|
|
242
|
+
// transcript (Stop/SessionEnd only fire on clean exit). Throttled.
|
|
243
|
+
await handleStopFamily(convGuid, hook, false, POST_TOOL_FLUSH_MS);
|
|
244
|
+
break;
|
|
221
245
|
case 'session-end':
|
|
222
246
|
await handleSessionEnd(convGuid, hook, source);
|
|
223
247
|
break;
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ import { logsCommand } from './commands/logs.js';
|
|
|
31
31
|
import { pageCommand } from './commands/page.js';
|
|
32
32
|
import { recordsCommand } from './commands/records.js';
|
|
33
33
|
import { fnCommand } from './commands/fn.js';
|
|
34
|
+
import { serviceCommand } from './commands/service.js';
|
|
34
35
|
import { jobCommand } from './commands/job.js';
|
|
35
36
|
import { rbacCommand } from './commands/rbac.js';
|
|
36
37
|
import { auditCommand } from './commands/audit.js';
|
|
@@ -47,6 +48,7 @@ import { relayCommand } from './commands/relay.js';
|
|
|
47
48
|
import { uninstallCommand } from './commands/uninstall.js';
|
|
48
49
|
import { approvalCommand } from './commands/approval.js';
|
|
49
50
|
import { gmailCommand } from './commands/gmail.js';
|
|
51
|
+
import { textCommand } from './commands/text.js';
|
|
50
52
|
import { HELP_SKILL_MAP, fetchAndPrintSkill } from './help-skills.js';
|
|
51
53
|
import { bold, dim, brand, muted, success } from './colors.js';
|
|
52
54
|
import { normalizeAliases } from './flag-aliases.js';
|
|
@@ -90,13 +92,19 @@ function configureHelp(cmd) {
|
|
|
90
92
|
});
|
|
91
93
|
}
|
|
92
94
|
const program = new Command();
|
|
95
|
+
// Global value-options (`--api-base <url>`) are only meaningful before the
|
|
96
|
+
// subcommand. Without this, commander interleaves program + subcommand option
|
|
97
|
+
// parsing and mis-reads a subcommand's `.requiredOption()` as missing when a
|
|
98
|
+
// global value-option precedes it (e.g. `gipity --api-base X workflow create
|
|
99
|
+
// --from Y`). enablePositionalOptions draws the boundary at the first command.
|
|
100
|
+
program.enablePositionalOptions();
|
|
93
101
|
// ── Command groups (logical ordering within each) ──────────────────────
|
|
94
102
|
const commonGroup = [skillCommand, projectCommand, addCommand, deployCommand];
|
|
95
103
|
const connectGroup = [claudeCommand, relayCommand];
|
|
96
104
|
const projectGroup = [domainCommand, statusCommand, initCommand];
|
|
97
105
|
const filesGroup = [fileCommand, syncCommand, pushCommand, uploadCommand];
|
|
98
|
-
const appBuildingGroup = [testCommand, fnCommand, jobCommand, dbCommand, logsCommand, workflowCommand, realtimeCommand, rbacCommand, auditCommand, recordsCommand];
|
|
99
|
-
const utilitiesGroup = [pageCommand, sandboxCommand, generateCommand, emailCommand, gmailCommand, locationCommand];
|
|
106
|
+
const appBuildingGroup = [testCommand, fnCommand, serviceCommand, jobCommand, dbCommand, logsCommand, workflowCommand, realtimeCommand, rbacCommand, auditCommand, recordsCommand];
|
|
107
|
+
const utilitiesGroup = [pageCommand, sandboxCommand, generateCommand, emailCommand, gmailCommand, locationCommand, textCommand];
|
|
100
108
|
const agentGroup = [chatCommand, memoryCommand, agentCommand, approvalCommand];
|
|
101
109
|
const setupGroup = [loginCommand, logoutCommand, creditsCommand, planCommand, doctorCommand, updateCommand, uninstallCommand];
|
|
102
110
|
const HELP_SECTIONS = [
|
|
@@ -170,6 +178,27 @@ for (const cmd of HELP_SECTIONS.flatMap(s => s.cmds)) {
|
|
|
170
178
|
configureHelp(cmd);
|
|
171
179
|
program.addCommand(cmd);
|
|
172
180
|
}
|
|
181
|
+
// ── Malformed invocation → print the error AND the command's help inline ──
|
|
182
|
+
// When an agent guesses the wrong shape (excess args, unknown command/option,
|
|
183
|
+
// missing arg), don't make it run `--help` as a second trip: Commander fires
|
|
184
|
+
// error() on the offending (sub)command, so showHelpAfterError(true) appends
|
|
185
|
+
// that exact command's help, and a labeled header names the canonical help
|
|
186
|
+
// invocation. addCommand doesn't inherit these settings, so apply recursively.
|
|
187
|
+
function fullCommandName(cmd) {
|
|
188
|
+
const parts = [];
|
|
189
|
+
for (let c = cmd; c; c = c.parent)
|
|
190
|
+
parts.unshift(c.name());
|
|
191
|
+
return parts.join(' ');
|
|
192
|
+
}
|
|
193
|
+
function enableHelpAfterError(cmd) {
|
|
194
|
+
cmd.showHelpAfterError(true);
|
|
195
|
+
cmd.configureOutput({
|
|
196
|
+
outputError: (str, write) => write(`${str.replace(/\n+$/, '')}\n\nShowing \`${fullCommandName(cmd)} --help\`:\n`),
|
|
197
|
+
});
|
|
198
|
+
for (const sub of cmd.commands)
|
|
199
|
+
enableHelpAfterError(sub);
|
|
200
|
+
}
|
|
201
|
+
enableHelpAfterError(program);
|
|
173
202
|
// Auto-fetch related skill docs when --help is run on mapped commands
|
|
174
203
|
const argv = process.argv.slice(2);
|
|
175
204
|
const hasHelp = argv.includes('--help') || argv.includes('-h');
|
package/dist/knowledge.js
CHANGED
|
@@ -30,12 +30,13 @@ Kits are reusable building blocks added to an existing app, not whole templates
|
|
|
30
30
|
- \`gipity add realtime\` - Multiplayer / presence / shared state - channels, host election, server-persisted sync. Engine-agnostic; works in any app.
|
|
31
31
|
- \`gipity add web-vision-mediapipe\` - On-device camera vision - gesture recognition, body pose, object detection. Runs fully client-side via MediaPipe Tasks; no server, no upload. Web only.
|
|
32
32
|
- \`gipity add chatbot\` - Drop-in chatbot - configurable persona, scope guardrails, static knowledge (20k budget), streaming responses. Headless engine + bubble widget; bring your own UI if you want. Works in any app.
|
|
33
|
-
- \`gipity add audio-align\` - Audio + lyrics -> word-level timing JSON. Demucs vocal isolation + MMS_FA forced alignment, runs as a Modal L4 GPU job (~$0.01 per 3-min song). For karaoke captions, subtitling, language learning, dubbing alignment
|
|
33
|
+
- \`gipity add audio-align\` - Audio + lyrics -> word-level timing JSON. Demucs vocal isolation + MMS_FA forced alignment, runs as a Modal L4 GPU job (~$0.01 per 3-min song). For karaoke captions, subtitling, language learning, dubbing alignment.
|
|
34
|
+
- \`gipity add i18n\` - Multi-language for web apps - language picker, locale persistence, RTL, plural/translation lookup. Scaffolds src/js/strings.js and wires it up; move your copy there and read it with t('key'). Web only.`;
|
|
34
35
|
export const SKILLS_CONTENT = `# Gipity Integration
|
|
35
36
|
|
|
36
37
|
Gipity is the cloud platform your project runs on - hosting, databases, deployment, file storage, code execution, workflows, and monitoring. Gip is the cloud agent that runs on Gipity.
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
Prefer the cheapest option that works - CLI and sandbox are instant and free, app services are runtime HTTP calls, \`gipity chat\` burns LLM tokens:
|
|
39
40
|
|
|
40
41
|
1. CLI commands (fast, no agent overhead). The \`gipity\` CLI covers add, deploy, db, fn, logs, browser, sync, memory, skill, and more. All commands support \`--json\`.
|
|
41
42
|
2. Cloud sandbox via \`gipity sandbox run\` - Docker container with pre-installed tools for media (ffmpeg, ImageMagick, sox), documents (pandoc, LibreOffice), and data (pandas, matplotlib, sqlite3). Run \`gipity skill read sandbox-tools\` for the full toolkit. No network from inside the sandbox - fetch what you need before sending it in.
|
|
@@ -46,7 +47,7 @@ You are the developer. Write files in this directory - they auto-sync to Gipity
|
|
|
46
47
|
|
|
47
48
|
## Use first-party services before reaching outside
|
|
48
49
|
|
|
49
|
-
Gipity ships
|
|
50
|
+
Gipity ships first-party services for what apps usually pull from third parties - auth, location/geocoding, LLM, image/audio/video generation, transcription, file uploads, realtime. Before calling an external API or adding an npm package for one of these, check \`gipity skill list\` for a match. First-party services need no API keys, cost less, and keep data in-house. Reach outside only when the catalog has no equivalent - and say so when you do.
|
|
50
51
|
|
|
51
52
|
## When to add a template
|
|
52
53
|
|
|
@@ -54,11 +55,19 @@ The full rule and definition of done are injected at the top of every session co
|
|
|
54
55
|
|
|
55
56
|
Build loop: \`gipity add\` → edit files → \`gipity deploy dev\` → \`gipity page inspect <url>\` → fix any errors → repeat until the definition of done is met.
|
|
56
57
|
|
|
58
|
+
Make your file changes and verify they landed, then run \`gipity deploy dev\` once. \`0 uploaded, N unchanged\` means nothing changed on disk - fix the files, don't re-run deploy or probe the environment.
|
|
59
|
+
|
|
60
|
+
Before telling the user the app is online, verify the source tree is consistent: no files named like \`* (conflict from *)*\`, and every package directory has its expected canonical entry file. If a conflict artifact exists, resolve it (keep one copy), re-deploy, and re-inspect before reporting done.
|
|
61
|
+
|
|
57
62
|
## CLI quick reference
|
|
58
63
|
|
|
59
64
|
Key commands: \`gipity add <template|kit>\`, \`gipity deploy dev\`, \`gipity sandbox run\`, \`gipity page inspect <url>\`, \`gipity db query "SQL"\`, \`gipity fn call <name>\`, \`gipity logs fn <name>\`, \`gipity skill read <name>\`.
|
|
60
65
|
Run \`gipity --help\` for the full list. Use \`--help\` on any command for details.
|
|
61
66
|
|
|
67
|
+
## Tool output is complete and synchronous
|
|
68
|
+
|
|
69
|
+
Every tool call returns its full output with that call. There is no output buffer to flush. Never run no-op commands (echo, date, sleep, repeated reads) to "retrieve" or "flush" lagged output - if a result looks empty or delayed, treat it as the actual result and move on, or re-run the real command once.
|
|
70
|
+
|
|
62
71
|
## Files and sync
|
|
63
72
|
|
|
64
73
|
Write files locally - hooks auto-push to Gipity on every save. Remote-generated files (images, audio from \`gipity chat\`) auto-pull. Use \`gipity sync\` if things get out of sync. Deletes are safe - use \`rollback\` with a datetime to undo, or \`file_version_restore\` for individual files.
|
|
@@ -85,6 +94,7 @@ App development skills:
|
|
|
85
94
|
- \`jobs\` - long-running CPU + GPU compute jobs (Python / Node / bash)
|
|
86
95
|
- \`realtime-scheduled-app\` - recipe: realtime presence/messages + DB function + scheduled poster, end-to-end
|
|
87
96
|
- \`web-app-basics\` - coding guidelines, file structure, HTML/CSS/JS patterns
|
|
97
|
+
- \`web-ui-patterns\` - default Gipity look (theme tokens) + web UI recipes - feeds, copy-to-clipboard
|
|
88
98
|
|
|
89
99
|
Kit skills (reusable building blocks - \`gipity add <kit>\`):
|
|
90
100
|
- \`audio-align\` - the audio-align kit: forced alignment of audio + lyrics into word-level timing JSON
|
package/dist/relay/daemon.js
CHANGED
|
@@ -891,15 +891,25 @@ export async function spawnGipityClaude(args, cwd, d) {
|
|
|
891
891
|
// as they arrive. That's the live-streaming path - every assistant
|
|
892
892
|
// message and tool call appears in the web CLI within a second of
|
|
893
893
|
// Claude emitting it.
|
|
894
|
+
// Per-dispatch tool_use_id → tool_name map so a `tool_result` event can
|
|
895
|
+
// be denormalized with its tool's name (the result block omits it).
|
|
896
|
+
const toolNames = new Map();
|
|
894
897
|
const splitter = createLineSplitter((line) => {
|
|
895
898
|
const evt = parseEvent(line, (reason, snippet) => {
|
|
896
899
|
log('warn', 'stream-json parse skipped line', { id: d.short_guid, reason, snippet });
|
|
897
900
|
});
|
|
898
901
|
if (!evt)
|
|
899
902
|
return;
|
|
900
|
-
const entries = mapEventToEntries(evt);
|
|
903
|
+
const entries = mapEventToEntries(evt, toolNames);
|
|
901
904
|
if (entries.length === 0)
|
|
902
905
|
return;
|
|
906
|
+
// Stamp the read time as the event-time hint (event_at). Stream-json
|
|
907
|
+
// carries no per-event timestamp; the daemon reads events as Claude
|
|
908
|
+
// emits them, so receipt time is a close, per-event proxy - far
|
|
909
|
+
// better than the single flush-time created_at on the whole batch.
|
|
910
|
+
const ts = new Date().toISOString();
|
|
911
|
+
for (const e of entries)
|
|
912
|
+
e.ts = ts;
|
|
903
913
|
// Fire-and-forget POST but tracked so the drain on exit can
|
|
904
914
|
// `allSettled` the set before we claim the spawn is done.
|
|
905
915
|
const p = postIngest(d.conversation_guid, entries)
|
|
@@ -62,8 +62,14 @@ function joinAssistantText(content) {
|
|
|
62
62
|
* assistant event may yield one `assistant` entry AND one `tool_use`
|
|
63
63
|
* entry per tool_use block within it (server persists each tool call
|
|
64
64
|
* as its own `role='tool'` row, then updates it when the matching
|
|
65
|
-
* `tool_result` arrives).
|
|
66
|
-
|
|
65
|
+
* `tool_result` arrives).
|
|
66
|
+
*
|
|
67
|
+
* `toolNames` (optional) is a per-dispatch `tool_use_id → tool_name`
|
|
68
|
+
* map threaded across events by the daemon: assistant events record
|
|
69
|
+
* each tool call's name, the later user event with the paired
|
|
70
|
+
* `tool_result` reads it back so the server can denormalize `tool_name`
|
|
71
|
+
* onto the tool row even when the result lands as a stub. */
|
|
72
|
+
export function mapEventToEntries(evt, toolNames) {
|
|
67
73
|
const out = [];
|
|
68
74
|
if (evt.type === 'system' && evt.subtype === 'init') {
|
|
69
75
|
const s = evt;
|
|
@@ -76,14 +82,16 @@ export function mapEventToEntries(evt) {
|
|
|
76
82
|
const content = Array.isArray(msg.content) ? msg.content : [];
|
|
77
83
|
const text = joinAssistantText(content);
|
|
78
84
|
if (text || content.length) {
|
|
79
|
-
out.push({ kind: 'assistant', text, blocks: content });
|
|
85
|
+
out.push({ kind: 'assistant', text, blocks: content, ...usageFields(msg) });
|
|
80
86
|
}
|
|
81
87
|
for (const block of content) {
|
|
82
88
|
if (block?.type === 'tool_use' && typeof block.id === 'string') {
|
|
89
|
+
const toolName = typeof block.name === 'string' ? block.name : 'tool';
|
|
90
|
+
toolNames?.set(block.id, toolName);
|
|
83
91
|
out.push({
|
|
84
92
|
kind: 'tool_use',
|
|
85
93
|
tool_use_id: block.id,
|
|
86
|
-
tool_name:
|
|
94
|
+
tool_name: toolName,
|
|
87
95
|
tool_input: block.input ?? null,
|
|
88
96
|
});
|
|
89
97
|
}
|
|
@@ -98,6 +106,7 @@ export function mapEventToEntries(evt) {
|
|
|
98
106
|
out.push({
|
|
99
107
|
kind: 'tool_result',
|
|
100
108
|
tool_use_id: block.tool_use_id,
|
|
109
|
+
tool_name: toolNames?.get(block.tool_use_id),
|
|
101
110
|
content: block.content ?? null,
|
|
102
111
|
is_error: Boolean(block.is_error),
|
|
103
112
|
});
|
|
@@ -105,10 +114,38 @@ export function mapEventToEntries(evt) {
|
|
|
105
114
|
}
|
|
106
115
|
return out;
|
|
107
116
|
}
|
|
108
|
-
// `result` is the final footer
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
117
|
+
// `result` is the final footer — a session-level total. Emit a `result`
|
|
118
|
+
// ingest entry carrying the cost so the server can record it on the
|
|
119
|
+
// conversation. (Per-turn tokens ride on the assistant entries above; cost is
|
|
120
|
+
// only ever here, and only on the stream path.)
|
|
121
|
+
if (evt.type === 'result') {
|
|
122
|
+
const r = evt;
|
|
123
|
+
if (typeof r.total_cost_usd === 'number' || typeof r.num_turns === 'number' || typeof r.duration_ms === 'number') {
|
|
124
|
+
out.push({
|
|
125
|
+
kind: 'result',
|
|
126
|
+
total_cost_usd: typeof r.total_cost_usd === 'number' ? r.total_cost_usd : undefined,
|
|
127
|
+
num_turns: typeof r.num_turns === 'number' ? r.num_turns : undefined,
|
|
128
|
+
duration_ms: typeof r.duration_ms === 'number' ? r.duration_ms : undefined,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
/** Pull token usage + model + stop_reason off an assistant stream `message`.
|
|
136
|
+
* Same shape as the transcript path's `usageFields` (kept in sync; the two
|
|
137
|
+
* capture modules don't share a module). Cost is NOT per-message. */
|
|
138
|
+
function usageFields(msg) {
|
|
139
|
+
const out = {};
|
|
140
|
+
const u = msg?.usage;
|
|
141
|
+
if (u && typeof u.input_tokens === 'number')
|
|
142
|
+
out.input_tokens = u.input_tokens;
|
|
143
|
+
if (u && typeof u.output_tokens === 'number')
|
|
144
|
+
out.output_tokens = u.output_tokens;
|
|
145
|
+
if (typeof msg?.model === 'string')
|
|
146
|
+
out.model = msg.model;
|
|
147
|
+
if (typeof msg?.stop_reason === 'string')
|
|
148
|
+
out.stop_reason = msg.stop_reason;
|
|
112
149
|
return out;
|
|
113
150
|
}
|
|
114
151
|
// ─── Line-buffered stream splitter ─────────────────────────────────────
|
package/dist/setup.js
CHANGED
|
@@ -66,6 +66,7 @@ export const PERMISSIONS_SETTINGS = {
|
|
|
66
66
|
'Bash(gipity file versions *)',
|
|
67
67
|
'Bash(gipity records *)',
|
|
68
68
|
'Bash(gipity fn *)',
|
|
69
|
+
'Bash(gipity service *)',
|
|
69
70
|
'Bash(gipity rbac *)',
|
|
70
71
|
'Bash(gipity audit *)',
|
|
71
72
|
'Bash(gipity generate *)',
|
|
@@ -93,9 +94,11 @@ export function resolveCaptureRunnerPath() {
|
|
|
93
94
|
// 1. File-sync hooks (PreToolUse / PostToolUse / UserPromptSubmit):
|
|
94
95
|
// installed unconditionally. Scaffold reminder + push/pull. Not
|
|
95
96
|
// related to conversation capture.
|
|
96
|
-
// 2. Capture hooks (SessionStart / Stop / SubagentStop / SessionEnd
|
|
97
|
-
//
|
|
98
|
-
//
|
|
97
|
+
// 2. Capture hooks (SessionStart / Stop / SubagentStop / SessionEnd, plus
|
|
98
|
+
// a throttled PostToolUse for mid-run flushing): mirror a terminal
|
|
99
|
+
// Claude Code session into the Gipity DB so the web CLI can display it
|
|
100
|
+
// read-only. The PostToolUse capture entry is merged alongside the
|
|
101
|
+
// file-sync one (see setupClaudeHooks). Toggled by the `captureHooks`
|
|
99
102
|
// field in `.gipity.json` - default on.
|
|
100
103
|
export const HOOKS_SETTINGS = {
|
|
101
104
|
hooks: {
|
|
@@ -153,6 +156,11 @@ function buildCaptureHookEntries(source) {
|
|
|
153
156
|
Stop: [{ hooks: [{ type: 'command', command: cmd('stop') }] }],
|
|
154
157
|
SubagentStop: [{ hooks: [{ type: 'command', command: cmd('subagent-stop') }] }],
|
|
155
158
|
SessionEnd: [{ hooks: [{ type: 'command', command: cmd('session-end') }] }],
|
|
159
|
+
// Mid-run incremental flush (matcher '' = every tool). Stop/SessionEnd only
|
|
160
|
+
// fire on a CLEAN exit, so without this a session that's killed/crashes mid-run
|
|
161
|
+
// (e.g. a long headless build that times out) loses its whole transcript. The
|
|
162
|
+
// runner throttles this so it's cheap. Merged alongside the file-sync PostToolUse.
|
|
163
|
+
PostToolUse: [{ matcher: '', hooks: [{ type: 'command', command: cmd('post-tool-use') }] }],
|
|
156
164
|
};
|
|
157
165
|
}
|
|
158
166
|
export function setupClaudeHooks() {
|
|
@@ -173,7 +181,13 @@ export function setupClaudeHooks() {
|
|
|
173
181
|
// feature for this project without affecting the file-sync hooks.
|
|
174
182
|
const captureEnabled = getConfig()?.captureHooks !== false;
|
|
175
183
|
const captureEntries = captureEnabled ? buildCaptureHookEntries('claude-code') : {};
|
|
176
|
-
|
|
184
|
+
// Merge per-event arrays rather than spread-overwriting: capture and file-sync
|
|
185
|
+
// both register PostToolUse, and a plain spread would drop one of them.
|
|
186
|
+
const mergedHooks = { ...HOOKS_SETTINGS.hooks };
|
|
187
|
+
for (const [event, entries] of Object.entries(captureEntries)) {
|
|
188
|
+
mergedHooks[event] = [...(mergedHooks[event] ?? []), ...entries];
|
|
189
|
+
}
|
|
190
|
+
settings.hooks = mergedHooks;
|
|
177
191
|
// Merge permissions (additive - preserve user's existing allows)
|
|
178
192
|
const perms = settings.permissions || {};
|
|
179
193
|
if (!perms.allow)
|
package/dist/sync.js
CHANGED
|
@@ -302,8 +302,16 @@ export function plan(local, remote, baseline) {
|
|
|
302
302
|
// unchanged × unchanged → noop
|
|
303
303
|
if (lSide === 'unchanged' && rSide === 'unchanged')
|
|
304
304
|
continue;
|
|
305
|
-
// unchanged × modified → download
|
|
305
|
+
// unchanged × modified → download, but ONLY if the remote genuinely advanced.
|
|
306
|
+
// Guards a read-after-write race: right after a local write+push, the push can
|
|
307
|
+
// advance the local baseline to the new version while the remote tree API still
|
|
308
|
+
// serves the OLD bytes (stale read). That makes remote look "modified" vs an
|
|
309
|
+
// already-updated baseline, and a blind download would silently clobber the
|
|
310
|
+
// just-written local file with a stale older version. A real remote change
|
|
311
|
+
// always carries a strictly newer serverVersion; an equal/older one is stale.
|
|
306
312
|
if (lSide === 'unchanged' && rSide === 'modified') {
|
|
313
|
+
if (B && R.serverVersion <= B.serverVersion)
|
|
314
|
+
continue;
|
|
307
315
|
actions.push({ path, kind: 'download', remoteSize: R.size });
|
|
308
316
|
continue;
|
|
309
317
|
}
|
|
@@ -359,8 +367,12 @@ export function plan(local, remote, baseline) {
|
|
|
359
367
|
actions.push({ path, kind: 'delete-remote', remoteSize: R.size, expectedServerVersion: B.serverVersion });
|
|
360
368
|
continue;
|
|
361
369
|
}
|
|
362
|
-
// deleted × modified → remote wins, restore locally
|
|
370
|
+
// deleted × modified → remote wins, restore locally — but only if the remote
|
|
371
|
+
// actually advanced past the baseline. A stale (older/equal) remote read must
|
|
372
|
+
// not resurrect a file the user intentionally deleted.
|
|
363
373
|
if (lSide === 'deleted' && rSide === 'modified') {
|
|
374
|
+
if (B && R.serverVersion <= B.serverVersion)
|
|
375
|
+
continue;
|
|
364
376
|
actions.push({
|
|
365
377
|
path, kind: 'download', remoteSize: R.size,
|
|
366
378
|
reason: 'local deleted but remote modified - remote preserved',
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gipity",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.365",
|
|
4
4
|
"description": "The full-stack platform tuned for AI agents. Database, storage, auth, functions, deploy, and drop-in kits - all agent-tuned. Pair with Claude Code or use standalone.",
|
|
5
5
|
"bin": {
|
|
6
|
-
"gipity": "
|
|
7
|
-
"gipcc": "
|
|
8
|
-
"gipccd": "
|
|
6
|
+
"gipity": "dist/updater/shim.js",
|
|
7
|
+
"gipcc": "dist/gipcc.js",
|
|
8
|
+
"gipccd": "dist/gipccd.js"
|
|
9
9
|
},
|
|
10
10
|
"type": "module",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc && chmod +x dist/index.js dist/gipcc.js dist/gipccd.js dist/updater/shim.js dist/updater/check.js",
|
|
13
13
|
"dev": "tsc --watch",
|
|
14
14
|
"test": "npm run test:smoke",
|
|
15
|
-
"test:smoke": "tsc && node --test dist/__tests__/utils.test.js dist/__tests__/config.test.js dist/__tests__/sync.test.js dist/__tests__/sync-apply.test.js dist/__tests__/sync-lock.test.js dist/__tests__/push-cas.test.js dist/__tests__/upload.test.js dist/__tests__/updater.test.js dist/__tests__/cli-smoke.test.js dist/__tests__/claude-noninteractive.test.js dist/__tests__/claude-trust.test.js dist/__tests__/relay-state.test.js dist/__tests__/relay-daemon.test.js dist/__tests__/relay-installers.test.js dist/__tests__/relay-bridge-abort.test.js dist/__tests__/relay-redact.test.js dist/__tests__/relay-machine-id.test.js dist/__tests__/stream-json.test.js dist/__tests__/relay-ingest-contract.test.js dist/__tests__/prompts.test.js dist/__tests__/capture-transcript.test.js dist/__tests__/flag-aliases.test.js dist/__tests__/adopt-cwd.test.js dist/__tests__/cli-cmd-agent.test.js dist/__tests__/cli-cmd-approval.test.js dist/__tests__/cli-cmd-audit.test.js dist/__tests__/cli-cmd-chat.test.js dist/__tests__/cli-cmd-credits.test.js dist/__tests__/cli-cmd-db.test.js dist/__tests__/cli-cmd-deploy.test.js dist/__tests__/cli-cmd-domain.test.js dist/__tests__/cli-cmd-email.test.js dist/__tests__/cli-cmd-file.test.js dist/__tests__/cli-cmd-fn.test.js dist/__tests__/cli-cmd-job.test.js dist/__tests__/cli-cmd-generate.test.js dist/__tests__/cli-cmd-gmail.test.js dist/__tests__/cli-cmd-info.test.js dist/__tests__/cli-cmd-init.test.js dist/__tests__/cli-cmd-location.test.js dist/__tests__/cli-cmd-login.test.js dist/__tests__/cli-cmd-logout.test.js dist/__tests__/cli-cmd-logs.test.js dist/__tests__/cli-cmd-memory.test.js dist/__tests__/cli-cmd-page.test.js dist/__tests__/cli-cmd-plan.test.js dist/__tests__/cli-cmd-project.test.js dist/__tests__/cli-cmd-rbac.test.js dist/__tests__/cli-cmd-realtime.test.js dist/__tests__/cli-cmd-records.test.js dist/__tests__/cli-cmd-relay.test.js dist/__tests__/cli-cmd-sandbox.test.js dist/__tests__/cli-cmd-add.test.js dist/__tests__/cli-cmd-skill.test.js dist/__tests__/cli-cmd-test.test.js dist/__tests__/cli-cmd-workflow.test.js dist/__tests__/setup-skills-block.test.js",
|
|
16
|
-
"test:e2e": "tsc && GIPITY_E2E=1 node --test --test-timeout=180000 dist/__tests__/cli-e2e-live.test.js"
|
|
15
|
+
"test:smoke": "tsc && node --test dist/__tests__/utils.test.js dist/__tests__/config.test.js dist/__tests__/sync.test.js dist/__tests__/sync-apply.test.js dist/__tests__/sync-lock.test.js dist/__tests__/push-cas.test.js dist/__tests__/upload.test.js dist/__tests__/updater.test.js dist/__tests__/cli-smoke.test.js dist/__tests__/claude-noninteractive.test.js dist/__tests__/claude-trust.test.js dist/__tests__/relay-state.test.js dist/__tests__/relay-daemon.test.js dist/__tests__/relay-installers.test.js dist/__tests__/relay-bridge-abort.test.js dist/__tests__/relay-redact.test.js dist/__tests__/relay-machine-id.test.js dist/__tests__/stream-json.test.js dist/__tests__/relay-ingest-contract.test.js dist/__tests__/prompts.test.js dist/__tests__/capture-transcript.test.js dist/__tests__/flag-aliases.test.js dist/__tests__/adopt-cwd.test.js dist/__tests__/cli-cmd-agent.test.js dist/__tests__/cli-cmd-approval.test.js dist/__tests__/cli-cmd-audit.test.js dist/__tests__/cli-cmd-chat.test.js dist/__tests__/cli-cmd-credits.test.js dist/__tests__/cli-cmd-db.test.js dist/__tests__/cli-cmd-deploy.test.js dist/__tests__/cli-cmd-domain.test.js dist/__tests__/cli-cmd-email.test.js dist/__tests__/cli-cmd-file.test.js dist/__tests__/cli-cmd-fn.test.js dist/__tests__/cli-cmd-service.test.js dist/__tests__/cli-cmd-job.test.js dist/__tests__/cli-cmd-generate.test.js dist/__tests__/cli-cmd-gmail.test.js dist/__tests__/cli-cmd-info.test.js dist/__tests__/cli-cmd-init.test.js dist/__tests__/cli-cmd-location.test.js dist/__tests__/cli-cmd-text.test.js dist/__tests__/cli-cmd-login.test.js dist/__tests__/cli-cmd-logout.test.js dist/__tests__/cli-cmd-logs.test.js dist/__tests__/cli-cmd-memory.test.js dist/__tests__/cli-cmd-page.test.js dist/__tests__/cli-cmd-plan.test.js dist/__tests__/cli-cmd-project.test.js dist/__tests__/cli-cmd-rbac.test.js dist/__tests__/cli-cmd-realtime.test.js dist/__tests__/cli-cmd-records.test.js dist/__tests__/cli-cmd-relay.test.js dist/__tests__/cli-cmd-sandbox.test.js dist/__tests__/cli-cmd-add.test.js dist/__tests__/cli-cmd-skill.test.js dist/__tests__/cli-cmd-test.test.js dist/__tests__/cli-cmd-workflow.test.js dist/__tests__/setup-skills-block.test.js dist/__tests__/setup-hooks.test.js",
|
|
16
|
+
"test:e2e": "tsc && GIPITY_E2E=1 node --test --test-timeout=180000 dist/__tests__/cli-e2e-live.test.js dist/__tests__/cli-e2e-services-media-live.test.js dist/__tests__/cli-e2e-workflow-live.test.js"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"commander": "^13.0.0",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"node": ">=18"
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
31
|
-
"dist",
|
|
31
|
+
"dist/**/*.js",
|
|
32
|
+
"!dist/__tests__/**",
|
|
32
33
|
"hooks"
|
|
33
34
|
],
|
|
34
35
|
"license": "MIT"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for the cwd-adoption helpers. Pure logic + small fs walks
|
|
3
|
-
* inside tmp dirs - no network, no real platform state.
|
|
4
|
-
*/
|
|
5
|
-
import { describe, it, before, after } from 'node:test';
|
|
6
|
-
import assert from 'node:assert/strict';
|
|
7
|
-
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'fs';
|
|
8
|
-
import { tmpdir, homedir } from 'os';
|
|
9
|
-
import { join, sep } from 'path';
|
|
10
|
-
import { scanForAdoption, isLikelyEmpty, canAdoptCwd, formatCwdLabel, formatBytes, } from '../adopt-cwd.js';
|
|
11
|
-
let root;
|
|
12
|
-
before(() => {
|
|
13
|
-
root = mkdtempSync(join(tmpdir(), 'gipity-adopt-test-'));
|
|
14
|
-
});
|
|
15
|
-
after(() => {
|
|
16
|
-
try {
|
|
17
|
-
rmSync(root, { recursive: true, force: true });
|
|
18
|
-
}
|
|
19
|
-
catch { /* best effort */ }
|
|
20
|
-
});
|
|
21
|
-
function mkdir(p) {
|
|
22
|
-
const full = join(root, p);
|
|
23
|
-
mkdirSync(full, { recursive: true });
|
|
24
|
-
return full;
|
|
25
|
-
}
|
|
26
|
-
function writeBytes(dir, name, n) {
|
|
27
|
-
writeFileSync(join(dir, name), Buffer.alloc(n));
|
|
28
|
-
}
|
|
29
|
-
describe('scanForAdoption', () => {
|
|
30
|
-
it('returns easy tier for a tiny project', () => {
|
|
31
|
-
const d = mkdir('easy');
|
|
32
|
-
writeBytes(d, 'a.txt', 10);
|
|
33
|
-
writeBytes(d, 'b.txt', 10);
|
|
34
|
-
const s = scanForAdoption(d);
|
|
35
|
-
assert.equal(s.tier, 'easy');
|
|
36
|
-
assert.equal(s.files, 2);
|
|
37
|
-
assert.equal(s.bytes, 20);
|
|
38
|
-
assert.equal(s.truncated, false);
|
|
39
|
-
});
|
|
40
|
-
it('handles a missing directory gracefully', () => {
|
|
41
|
-
const s = scanForAdoption(join(root, 'no-such-dir'));
|
|
42
|
-
assert.equal(s.tier, 'easy');
|
|
43
|
-
assert.equal(s.files, 0);
|
|
44
|
-
});
|
|
45
|
-
it('walks nested directories', () => {
|
|
46
|
-
const d = mkdir('nested');
|
|
47
|
-
const sub = mkdir('nested/sub/sub2');
|
|
48
|
-
writeBytes(d, 'top.txt', 1);
|
|
49
|
-
writeBytes(sub, 'deep.txt', 2);
|
|
50
|
-
const s = scanForAdoption(d);
|
|
51
|
-
assert.equal(s.files, 2);
|
|
52
|
-
assert.equal(s.bytes, 3);
|
|
53
|
-
});
|
|
54
|
-
it('returns moderate tier when over the easy file-count threshold', () => {
|
|
55
|
-
const d = mkdir('moderate-files');
|
|
56
|
-
for (let i = 0; i < 250; i++)
|
|
57
|
-
writeBytes(d, `f${i}.txt`, 1);
|
|
58
|
-
const s = scanForAdoption(d);
|
|
59
|
-
assert.equal(s.tier, 'moderate');
|
|
60
|
-
assert.equal(s.truncated, false);
|
|
61
|
-
});
|
|
62
|
-
it('returns refuse + truncated when over the refuse file-count threshold', () => {
|
|
63
|
-
const d = mkdir('refuse-files');
|
|
64
|
-
for (let i = 0; i < 2100; i++)
|
|
65
|
-
writeBytes(d, `f${i}.txt`, 1);
|
|
66
|
-
const s = scanForAdoption(d);
|
|
67
|
-
assert.equal(s.tier, 'refuse');
|
|
68
|
-
assert.equal(s.truncated, true);
|
|
69
|
-
});
|
|
70
|
-
it('skips sync-ignored entries (node_modules, .git)', () => {
|
|
71
|
-
const d = mkdir('with-junk');
|
|
72
|
-
writeBytes(d, 'real.txt', 1);
|
|
73
|
-
const nm = mkdir('with-junk/node_modules');
|
|
74
|
-
writeBytes(nm, 'should-not-count.txt', 999_999);
|
|
75
|
-
const git = mkdir('with-junk/.git');
|
|
76
|
-
writeBytes(git, 'also-skip.txt', 999_999);
|
|
77
|
-
const s = scanForAdoption(d);
|
|
78
|
-
assert.equal(s.files, 1);
|
|
79
|
-
assert.equal(s.bytes, 1);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
describe('isLikelyEmpty', () => {
|
|
83
|
-
it('true for a truly empty dir', () => {
|
|
84
|
-
const d = mkdir('empty');
|
|
85
|
-
assert.equal(isLikelyEmpty(d), true);
|
|
86
|
-
});
|
|
87
|
-
it('true for a dir with only sync-ignored entries', () => {
|
|
88
|
-
const d = mkdir('only-junk');
|
|
89
|
-
mkdir('only-junk/node_modules');
|
|
90
|
-
mkdir('only-junk/.git');
|
|
91
|
-
assert.equal(isLikelyEmpty(d), true);
|
|
92
|
-
});
|
|
93
|
-
it('false when there is any real file', () => {
|
|
94
|
-
const d = mkdir('not-empty');
|
|
95
|
-
writeBytes(d, 'hello.md', 1);
|
|
96
|
-
assert.equal(isLikelyEmpty(d), false);
|
|
97
|
-
});
|
|
98
|
-
it('true when the dir does not exist', () => {
|
|
99
|
-
assert.equal(isLikelyEmpty(join(root, 'ghost')), true);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
describe('canAdoptCwd', () => {
|
|
103
|
-
it('refuses the filesystem root', () => {
|
|
104
|
-
assert.equal(canAdoptCwd(sep), false);
|
|
105
|
-
});
|
|
106
|
-
it('refuses the user\'s home directory', () => {
|
|
107
|
-
assert.equal(canAdoptCwd(homedir()), false);
|
|
108
|
-
});
|
|
109
|
-
it('refuses system dirs', () => {
|
|
110
|
-
assert.equal(canAdoptCwd('/tmp'), false);
|
|
111
|
-
assert.equal(canAdoptCwd('/etc'), false);
|
|
112
|
-
assert.equal(canAdoptCwd('/usr'), false);
|
|
113
|
-
});
|
|
114
|
-
it('allows a subdirectory of /tmp', () => {
|
|
115
|
-
const d = mkdir('allowed-subdir');
|
|
116
|
-
assert.equal(canAdoptCwd(d), true);
|
|
117
|
-
});
|
|
118
|
-
it('refuses a workspace-parent (depth ≤1 below home with 3+ git children)', () => {
|
|
119
|
-
// Simulate ~/Workspace/{a,b,c}/.git
|
|
120
|
-
const ws = mkdtempSync(join(homedir(), 'gipity-adopt-ws-'));
|
|
121
|
-
try {
|
|
122
|
-
for (const sub of ['a', 'b', 'c']) {
|
|
123
|
-
mkdirSync(join(ws, sub, '.git'), { recursive: true });
|
|
124
|
-
}
|
|
125
|
-
assert.equal(canAdoptCwd(ws), false);
|
|
126
|
-
}
|
|
127
|
-
finally {
|
|
128
|
-
rmSync(ws, { recursive: true, force: true });
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
it('allows a single-project dir even at depth ≤1 under home', () => {
|
|
132
|
-
const single = mkdtempSync(join(homedir(), 'gipity-adopt-single-'));
|
|
133
|
-
try {
|
|
134
|
-
mkdirSync(join(single, '.git'), { recursive: true });
|
|
135
|
-
assert.equal(canAdoptCwd(single), true);
|
|
136
|
-
}
|
|
137
|
-
finally {
|
|
138
|
-
rmSync(single, { recursive: true, force: true });
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
describe('formatCwdLabel', () => {
|
|
143
|
-
it('returns "~" for the home dir', () => {
|
|
144
|
-
assert.equal(formatCwdLabel(homedir()), '~');
|
|
145
|
-
});
|
|
146
|
-
it('uses ~/tail when 1-2 segments deep in home', () => {
|
|
147
|
-
assert.equal(formatCwdLabel(join(homedir(), 'Github')), '~/Github');
|
|
148
|
-
assert.equal(formatCwdLabel(join(homedir(), 'Github', 'Gipity')), '~/Github/Gipity');
|
|
149
|
-
});
|
|
150
|
-
it('uses ~/…/last-2 when deeper in home', () => {
|
|
151
|
-
const deep = join(homedir(), 'a', 'b', 'c', 'd');
|
|
152
|
-
assert.equal(formatCwdLabel(deep), '~/…/c/d');
|
|
153
|
-
});
|
|
154
|
-
it('shows parent/this for non-home paths', () => {
|
|
155
|
-
assert.equal(formatCwdLabel('/tmp/scratch'), 'tmp/scratch');
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
describe('formatBytes', () => {
|
|
159
|
-
it('B for sub-KB', () => {
|
|
160
|
-
assert.equal(formatBytes(0), '0 B');
|
|
161
|
-
assert.equal(formatBytes(512), '512 B');
|
|
162
|
-
});
|
|
163
|
-
it('KB for sub-MB', () => {
|
|
164
|
-
assert.equal(formatBytes(1024), '1.0 KB');
|
|
165
|
-
assert.equal(formatBytes(2048), '2.0 KB');
|
|
166
|
-
});
|
|
167
|
-
it('MB for sub-GB', () => {
|
|
168
|
-
assert.equal(formatBytes(1024 * 1024), '1.0 MB');
|
|
169
|
-
assert.equal(formatBytes(50 * 1024 * 1024), '50.0 MB');
|
|
170
|
-
});
|
|
171
|
-
it('GB for ≥ GB (fixes the "1024.0 MB" overflow at the refuse threshold)', () => {
|
|
172
|
-
assert.equal(formatBytes(1024 * 1024 * 1024), '1.00 GB');
|
|
173
|
-
assert.equal(formatBytes(2.5 * 1024 * 1024 * 1024), '2.50 GB');
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
//# sourceMappingURL=adopt-cwd.test.js.map
|