gipity 1.0.347 → 1.0.356
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 +1 -1
- package/dist/adopt-cwd.js +1 -0
- package/dist/commands/add.js +136 -9
- package/dist/commands/logs.js +79 -0
- package/dist/commands/page-eval.js +31 -0
- package/dist/commands/page-inspect.js +91 -62
- package/dist/commands/page-screenshot.js +1 -1
- package/dist/commands/page.js +18 -0
- package/dist/commands/project.js +1 -0
- package/dist/commands/workflow.js +63 -16
- package/dist/flag-aliases.js +41 -2
- package/dist/index.js +3 -4
- package/dist/knowledge.js +5 -4
- package/dist/project-setup.js +24 -0
- package/dist/setup.js +1 -1
- package/dist/template-vars.js +156 -0
- package/package.json +7 -6
- 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-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 -33
- 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__/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-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/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 -12
- 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 -26
- 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/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
package/README.md
CHANGED
|
@@ -141,7 +141,7 @@ gipity sync down # Pull remote changes
|
|
|
141
141
|
| `gipity add <template>` | Add a template (web-simple, 2d-game, 3d-world, web-fullstack, api) |
|
|
142
142
|
| `gipity test` | Run project tests in sandboxed containers |
|
|
143
143
|
| `gipity logs fn <name>` | View function execution logs |
|
|
144
|
-
| `gipity page
|
|
144
|
+
| `gipity page inspect <url>` | Inspect a URL: console errors, performance, failed resources |
|
|
145
145
|
| `gipity records` | Query and manage Records API tables |
|
|
146
146
|
| `gipity fn` | Manage and call serverless functions |
|
|
147
147
|
| `gipity rbac` | Manage RBAC policies |
|
package/dist/adopt-cwd.js
CHANGED
package/dist/commands/add.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
1
4
|
import { Command } from 'commander';
|
|
2
5
|
import { post } from '../api.js';
|
|
3
6
|
import { requireConfig } from '../config.js';
|
|
@@ -27,12 +30,113 @@ function printCatalog() {
|
|
|
27
30
|
for (const k of KITS)
|
|
28
31
|
console.log(` ${k.key} ${muted('- ' + k.hint)}`);
|
|
29
32
|
console.log('');
|
|
30
|
-
console.log(muted('
|
|
33
|
+
console.log(`${bold('Local path')} ${muted('- install from a directory on disk (template or kit)')}`);
|
|
34
|
+
console.log(` ${muted('gipity add ./path/to/template (or ~/path, /abs/path)')}`);
|
|
35
|
+
console.log(` ${muted('gipity add ./path/to/kit (auto-detected via package.json gipity.install)')}`);
|
|
31
36
|
console.log('');
|
|
37
|
+
console.log(muted('Usage: gipity add <name|path> [--title <t>] [--description <d>] [--force]'));
|
|
38
|
+
console.log('');
|
|
39
|
+
}
|
|
40
|
+
// ─── Local-path payload mode ────────────────────────────────────────────────
|
|
41
|
+
//
|
|
42
|
+
// `gipity add ./path/to/template` walks a directory and ships the contents to
|
|
43
|
+
// the server as a JSON payload, instead of asking the server to look the name
|
|
44
|
+
// up in its bundled catalog. This is the dev loop for template authors: you
|
|
45
|
+
// can iterate on `registry/templates/<name>/` and push to a real app without
|
|
46
|
+
// having to redeploy the server.
|
|
47
|
+
//
|
|
48
|
+
// The server-side wire shape this builds matches addSchema.files in
|
|
49
|
+
// platform/server/src/routes/projects/add.ts (same field names, same encoding
|
|
50
|
+
// discriminator).
|
|
51
|
+
const TEXT_EXTENSIONS = new Set([
|
|
52
|
+
'.html', '.htm', '.css', '.js', '.mjs', '.ts', '.tsx', '.jsx',
|
|
53
|
+
'.json', '.yaml', '.yml', '.toml',
|
|
54
|
+
'.md', '.markdown', '.txt', '.csv', '.xml', '.svg',
|
|
55
|
+
'.py', '.sh', '.bash', '.sql',
|
|
56
|
+
'.env', '.gitignore', '.dockerignore',
|
|
57
|
+
]);
|
|
58
|
+
// Anything not in TEXT_EXTENSIONS gets base64 - safer than guessing. The
|
|
59
|
+
// server-side BINARY_MIME table maps the extension back to a content-type.
|
|
60
|
+
const SKIP_DIR_NAMES = new Set([
|
|
61
|
+
'node_modules', '.git', 'dist', 'build', '__pycache__', '.next', '.vite',
|
|
62
|
+
'.gipity', // local project state dir - never belongs in a template payload
|
|
63
|
+
]);
|
|
64
|
+
const SKIP_FILE_NAMES = new Set(['.DS_Store', 'Thumbs.db']);
|
|
65
|
+
const MAX_PAYLOAD_BYTES = 25 * 1024 * 1024; // 25 MB (server caps body at 30 MB)
|
|
66
|
+
const MAX_FILES = 500;
|
|
67
|
+
function looksLikePath(name) {
|
|
68
|
+
// ./ or ../ or absolute / or ~/ - and any string that already contains a
|
|
69
|
+
// separator (cross-platform: forward or back slash). Bare catalog keys like
|
|
70
|
+
// "web-simple" or "karaoke-captions" hit the server lookup path; anything
|
|
71
|
+
// that walks a filesystem hits payload mode.
|
|
72
|
+
return /^[./~]/.test(name) || name.includes('/') || name.includes('\\');
|
|
73
|
+
}
|
|
74
|
+
function resolveLocalPath(input) {
|
|
75
|
+
if (input.startsWith('~'))
|
|
76
|
+
return path.resolve(os.homedir() + input.slice(1));
|
|
77
|
+
return path.resolve(input);
|
|
78
|
+
}
|
|
79
|
+
/** Sniff whether a local-path payload is a kit or a template, mirroring the
|
|
80
|
+
* server-side sniff in routes/projects/add.ts. Templates ship `gipity.yaml`
|
|
81
|
+
* at the root; kits ship `package.json` with a `gipity.install` block. The
|
|
82
|
+
* CLI sends the result as a `kind` hint so the server doesn't have to
|
|
83
|
+
* re-do the sniff on the encoded payload. */
|
|
84
|
+
function sniffPayloadKind(files) {
|
|
85
|
+
const pkg = files.find(f => f.path === 'package.json');
|
|
86
|
+
if (!pkg)
|
|
87
|
+
return 'template';
|
|
88
|
+
if (pkg.encoding !== 'utf8')
|
|
89
|
+
return 'template'; // base64'd package.json would be weird; default to template
|
|
90
|
+
try {
|
|
91
|
+
const manifest = JSON.parse(pkg.content);
|
|
92
|
+
if (manifest?.gipity?.install)
|
|
93
|
+
return 'kit';
|
|
94
|
+
}
|
|
95
|
+
catch { /* fall through */ }
|
|
96
|
+
return 'template';
|
|
97
|
+
}
|
|
98
|
+
function buildLocalPayload(rootDir) {
|
|
99
|
+
const stat = fs.statSync(rootDir);
|
|
100
|
+
if (!stat.isDirectory()) {
|
|
101
|
+
throw new Error(`Not a directory: ${rootDir}`);
|
|
102
|
+
}
|
|
103
|
+
const files = [];
|
|
104
|
+
let totalBytes = 0;
|
|
105
|
+
function walk(dir, prefix) {
|
|
106
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
107
|
+
if (entry.isDirectory()) {
|
|
108
|
+
if (SKIP_DIR_NAMES.has(entry.name))
|
|
109
|
+
continue;
|
|
110
|
+
walk(path.join(dir, entry.name), prefix ? `${prefix}/${entry.name}` : entry.name);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (!entry.isFile())
|
|
114
|
+
continue; // skip symlinks, sockets, etc.
|
|
115
|
+
if (SKIP_FILE_NAMES.has(entry.name))
|
|
116
|
+
continue;
|
|
117
|
+
if (files.length >= MAX_FILES) {
|
|
118
|
+
throw new Error(`Too many files (>${MAX_FILES}). Trim the template or raise the server cap.`);
|
|
119
|
+
}
|
|
120
|
+
const fullPath = path.join(dir, entry.name);
|
|
121
|
+
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
122
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
123
|
+
const buf = fs.readFileSync(fullPath);
|
|
124
|
+
const isText = TEXT_EXTENSIONS.has(ext);
|
|
125
|
+
const content = isText ? buf.toString('utf8') : buf.toString('base64');
|
|
126
|
+
const encoding = isText ? 'utf8' : 'base64';
|
|
127
|
+
totalBytes += content.length;
|
|
128
|
+
if (totalBytes > MAX_PAYLOAD_BYTES) {
|
|
129
|
+
throw new Error(`Payload exceeds ${Math.round(MAX_PAYLOAD_BYTES / 1024 / 1024)} MB cap.`);
|
|
130
|
+
}
|
|
131
|
+
files.push({ path: relPath, content, encoding });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
walk(rootDir, '');
|
|
135
|
+
return { name: path.basename(rootDir), files };
|
|
32
136
|
}
|
|
33
137
|
export const addCommand = new Command('add')
|
|
34
|
-
.description('Add a template (scaffold an app) or a kit (reusable building block) to the project')
|
|
35
|
-
.argument('[name]', 'Template
|
|
138
|
+
.description('Add a template (scaffold an app) or a kit (reusable building block) to the project. Pass ./path/to/dir to install a local template directly.')
|
|
139
|
+
.argument('[name]', 'Template/kit key, OR a local directory path (./, ~/, or /abs). Omit to list the catalog.')
|
|
36
140
|
.option('--title <title>', 'App title - templates only (defaults to project name)')
|
|
37
141
|
.option('--description <desc>', 'App description for meta tags - templates only')
|
|
38
142
|
.option('--force', 'Templates only: overwrite any colliding files')
|
|
@@ -43,12 +147,35 @@ export const addCommand = new Command('add')
|
|
|
43
147
|
return;
|
|
44
148
|
}
|
|
45
149
|
const config = requireConfig();
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
150
|
+
// Local-path payload mode kicks in when `name` looks like a path - bare
|
|
151
|
+
// names still go through the server's bundled catalog like before.
|
|
152
|
+
let body;
|
|
153
|
+
if (looksLikePath(name)) {
|
|
154
|
+
const resolved = resolveLocalPath(name);
|
|
155
|
+
if (!fs.existsSync(resolved)) {
|
|
156
|
+
throw new Error(`Local template/kit not found: ${resolved}`);
|
|
157
|
+
}
|
|
158
|
+
const { name: labelName, files } = buildLocalPayload(resolved);
|
|
159
|
+
const kind = sniffPayloadKind(files);
|
|
160
|
+
console.log(muted(`Uploading ${files.length} file(s) from ${resolved} (${kind}) ...`));
|
|
161
|
+
body = {
|
|
162
|
+
name: labelName,
|
|
163
|
+
title: opts.title,
|
|
164
|
+
description: opts.description,
|
|
165
|
+
force: opts.force,
|
|
166
|
+
files,
|
|
167
|
+
kind,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
body = {
|
|
172
|
+
name,
|
|
173
|
+
title: opts.title,
|
|
174
|
+
description: opts.description,
|
|
175
|
+
force: opts.force,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const res = await post(`/projects/${config.projectGuid}/add`, body);
|
|
52
179
|
// Pull the created/installed files down to local.
|
|
53
180
|
const syncResult = await sync({ interactive: false });
|
|
54
181
|
const data = res.data;
|
package/dist/commands/logs.js
CHANGED
|
@@ -33,4 +33,83 @@ logsCommand
|
|
|
33
33
|
console.log(` ${muted(time)} ${status} ${dur} ${trigger}${err}`);
|
|
34
34
|
}
|
|
35
35
|
}));
|
|
36
|
+
logsCommand
|
|
37
|
+
.command('app')
|
|
38
|
+
.description('Unified recent activity for this app — JS errors, failed function calls, failed services, network failures. Designed for agents debugging a deployed app.')
|
|
39
|
+
.option('--since <window>', "Window: 5m / 10m / 30m / 1h / 6h / 24h / 7d", '10m')
|
|
40
|
+
.option('--severity <level>', 'error | warn | network | all', 'all')
|
|
41
|
+
.option('--type <list>', "Comma-separated: errors,functions,services,traffic. Default excludes traffic (high volume).")
|
|
42
|
+
.option('--filter <pattern>', 'Substring match against message / fn name / path (case-insensitive)')
|
|
43
|
+
.option('--limit <n>', 'Max entries', '100')
|
|
44
|
+
.option('--json', 'Output as JSON (parseable by agents / pipes)')
|
|
45
|
+
.addHelpText('after', `
|
|
46
|
+
Examples:
|
|
47
|
+
$ gipity logs app Last 10 min of errors + fn failures
|
|
48
|
+
$ gipity logs app --since 1h Last hour
|
|
49
|
+
$ gipity logs app --severity network Only fetch/XHR failures
|
|
50
|
+
$ gipity logs app --filter song-create Anything mentioning song-create
|
|
51
|
+
$ gipity logs app --type errors Only JS errors
|
|
52
|
+
$ gipity logs app --json | jq .data.entries[0] Pipe-friendly
|
|
53
|
+
`)
|
|
54
|
+
.action((opts) => run('App logs', async () => {
|
|
55
|
+
const config = requireConfig();
|
|
56
|
+
const limit = parseInt(opts.limit, 10) || 100;
|
|
57
|
+
const qs = new URLSearchParams();
|
|
58
|
+
qs.set('since', String(opts.since));
|
|
59
|
+
qs.set('severity', String(opts.severity));
|
|
60
|
+
if (opts.type)
|
|
61
|
+
qs.set('type', String(opts.type));
|
|
62
|
+
if (opts.filter)
|
|
63
|
+
qs.set('filter', String(opts.filter));
|
|
64
|
+
qs.set('limit', String(limit));
|
|
65
|
+
const res = await get(`/projects/${config.projectGuid}/logs/app?${qs.toString()}`);
|
|
66
|
+
if (opts.json) {
|
|
67
|
+
console.log(JSON.stringify(res.data));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const { entries, since, types, severity, truncated } = res.data;
|
|
71
|
+
if (entries.length === 0) {
|
|
72
|
+
console.log(`No activity in the last ${since} ${muted(`(severity=${severity} types=${types.join(',')})`)}.`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
console.log(`${bold(`Recent activity`)} ${muted(`(last ${since}, ${entries.length}${truncated ? '+' : ''} entries, severity=${severity})`)}\n`);
|
|
76
|
+
for (const e of entries) {
|
|
77
|
+
const time = new Date(e.at).toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
78
|
+
const kindColor = e.kind === 'error' ? clrError : e.kind === 'function' ? warning : e.kind === 'service' ? warning : muted;
|
|
79
|
+
const kindTag = kindColor(`[${e.kind.padEnd(8)}]`);
|
|
80
|
+
console.log(`${muted(time)} ${kindTag} ${e.summary}`);
|
|
81
|
+
// Per-kind drilldown lines — what an agent most often needs without
|
|
82
|
+
// having to re-fetch the row.
|
|
83
|
+
const d = e.detail;
|
|
84
|
+
if (e.kind === 'error') {
|
|
85
|
+
const capturedBy = d.captured_by;
|
|
86
|
+
const url = d.network_url;
|
|
87
|
+
const status = d.network_status;
|
|
88
|
+
if (url)
|
|
89
|
+
console.log(` ${muted(`${capturedBy} → ${d.network_method || 'GET'} ${url} (${status ?? 'failed'})`)}`);
|
|
90
|
+
if (d.network_response_snippet)
|
|
91
|
+
console.log(` ${muted(`resp: ${String(d.network_response_snippet).slice(0, 160)}`)}`);
|
|
92
|
+
const corr = d.correlated_function_log;
|
|
93
|
+
if (corr) {
|
|
94
|
+
console.log(` ${muted(`└─ server fn ${corr.function_name} → ${corr.status}${corr.error_message ? ': ' + String(corr.error_message).slice(0, 100) : ''}`)}`);
|
|
95
|
+
}
|
|
96
|
+
const breadcrumbs = d.breadcrumbs;
|
|
97
|
+
if (breadcrumbs && breadcrumbs.length > 0) {
|
|
98
|
+
const lastFew = breadcrumbs.slice(-3).map(b => `${b.kind}${b.detail?.selector || b.detail?.url || b.detail?.path ? `:${b.detail.selector || b.detail.url || b.detail.path}` : ''}`).join(' → ');
|
|
99
|
+
console.log(` ${muted(`crumbs: ${lastFew}`)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (e.kind === 'function') {
|
|
103
|
+
const dur = d.duration_ms;
|
|
104
|
+
console.log(` ${muted(`${d.trigger_type} • ${dur ?? '?'}ms`)}${d.error_message ? muted(' • ') + clrError(String(d.error_message).slice(0, 200)) : ''}`);
|
|
105
|
+
}
|
|
106
|
+
if (e.kind === 'service') {
|
|
107
|
+
const dur = d.latency_ms;
|
|
108
|
+
console.log(` ${muted(`${d.service} (${d.provider ?? '?'}/${d.model ?? '?'}) • ${dur ?? '?'}ms`)}${d.error_message ? muted(' • ') + clrError(String(d.error_message).slice(0, 200)) : ''}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (truncated) {
|
|
112
|
+
console.log(`\n${muted(`(truncated at ${limit} entries — bump --limit or narrow --filter)`)}`);
|
|
113
|
+
}
|
|
114
|
+
}));
|
|
36
115
|
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { post } from '../api.js';
|
|
3
|
+
import { brand, bold, muted } from '../colors.js';
|
|
4
|
+
import { run } from '../helpers/index.js';
|
|
5
|
+
// The long-tail escape hatch alongside `page inspect`'s fixed bundle: when the
|
|
6
|
+
// curated metrics don't cover what you need (computed styles, element rects,
|
|
7
|
+
// visibility, z-index stacks), eval an expression in page context and get the
|
|
8
|
+
// serialized result back. Runs in the same browser sandbox as inspect.
|
|
9
|
+
export const pageEvalCommand = new Command('eval')
|
|
10
|
+
.description('Evaluate a JS expression in a real browser on a page (DOM, computed styles, element rects)')
|
|
11
|
+
.argument('<url>', 'URL to load')
|
|
12
|
+
.argument('<expr>', 'JavaScript expression to evaluate in page context (result is JSON-serialized)')
|
|
13
|
+
.option('--wait <ms>', 'Sleep this many ms after DOMContentLoaded before evaluating (lets late async work settle)', '500')
|
|
14
|
+
.option('--json', 'Output as JSON')
|
|
15
|
+
.action((url, expr, opts) => run('Page eval', async () => {
|
|
16
|
+
const parsedWait = parseInt(opts.wait, 10);
|
|
17
|
+
const waitMs = Number.isFinite(parsedWait) && parsedWait >= 0 ? parsedWait : 500;
|
|
18
|
+
const res = await post('/tools/browser/eval', { url, expr, waitMs });
|
|
19
|
+
const d = res.data;
|
|
20
|
+
if (opts.json) {
|
|
21
|
+
console.log(JSON.stringify(d));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
console.log(`\n${brand('Eval')} ${bold(d.url || url)}`);
|
|
25
|
+
console.log(` ${muted('Expression:')} ${expr}`);
|
|
26
|
+
console.log(`\n${d.result || muted('(empty result)')}`);
|
|
27
|
+
if (d.truncated)
|
|
28
|
+
console.log(muted('\n(result truncated to fit context - narrow the expression for the full value)'));
|
|
29
|
+
console.log('');
|
|
30
|
+
}));
|
|
31
|
+
//# sourceMappingURL=page-eval.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
1
|
+
import { Command, Option } from 'commander';
|
|
2
2
|
import { post } from '../api.js';
|
|
3
3
|
import { formatSize } from '../utils.js';
|
|
4
4
|
import { brand, bold, error as clrError, warning, muted, info } from '../colors.js';
|
|
@@ -19,78 +19,107 @@ function shortUrl(url, truncate = true, maxLen = 100) {
|
|
|
19
19
|
const tailLen = Math.floor(keep / 2);
|
|
20
20
|
return result.slice(0, headLen) + '…' + result.slice(-tailLen);
|
|
21
21
|
}
|
|
22
|
-
export const pageInspectCommand = new Command('
|
|
23
|
-
.description('Inspect a web page')
|
|
22
|
+
export const pageInspectCommand = new Command('inspect')
|
|
23
|
+
.description('Inspect a web page (console, failed resources, timing, layout overflow)')
|
|
24
24
|
.argument('<url>', 'URL to inspect')
|
|
25
25
|
.option('--wait <ms>', 'Sleep this many ms after DOMContentLoaded before capturing (lets late async/LCP work settle)', '500')
|
|
26
26
|
.option('--json', 'Output as JSON')
|
|
27
27
|
.option('--no-truncate', 'Show full URLs instead of truncating long ones with middle-ellipsis')
|
|
28
|
-
.option('--all', 'Include render-blocking, large resources, oversized images, and LCP detail')
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
console.log(JSON.stringify(b));
|
|
38
|
-
return;
|
|
28
|
+
.option('--all', 'Include render-blocking, large resources, oversized images, overflow culprits, and LCP detail')
|
|
29
|
+
// Hidden redirect: agents reach for `page inspect --screenshot`. We don't take
|
|
30
|
+
// an image here (`page screenshot` is the single path for that) — just point there.
|
|
31
|
+
.addOption(new Option('--screenshot [path]', 'Capture a screenshot').hideHelp())
|
|
32
|
+
.action((url, opts) => {
|
|
33
|
+
if (opts.screenshot !== undefined) {
|
|
34
|
+
console.error(clrError('page inspect does not capture screenshots. Use page screenshot:'));
|
|
35
|
+
console.error(` gipity page screenshot ${url}${typeof opts.screenshot === 'string' ? ` -o ${opts.screenshot}` : ''}`);
|
|
36
|
+
process.exit(1);
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
console.log(` ${muted('Load:')} ${timing.load}ms`);
|
|
51
|
-
if (showAll && b.lcp) {
|
|
52
|
-
console.log(` LCP: ${b.lcp.time}ms (${b.lcp.element}${b.lcp.url ? ' ' + shortUrl(b.lcp.url, truncate) : ''})`);
|
|
53
|
-
}
|
|
54
|
-
// ── Console ──
|
|
55
|
-
if (b.console?.length > 0) {
|
|
56
|
-
console.log(`\n ${bold('Console')} ${muted(`(${b.console.length})`)}:`);
|
|
57
|
-
for (const line of b.console) {
|
|
58
|
-
console.log(` ${warning(line)}`);
|
|
38
|
+
return run('Page inspect', async () => {
|
|
39
|
+
const parsedWait = parseInt(opts.wait, 10);
|
|
40
|
+
const waitMs = Number.isFinite(parsedWait) && parsedWait >= 0 ? parsedWait : 500;
|
|
41
|
+
const truncate = opts.truncate !== false;
|
|
42
|
+
const showAll = opts.all === true;
|
|
43
|
+
const res = await post(`/tools/browser/inspect`, { url, waitMs });
|
|
44
|
+
const b = res.data;
|
|
45
|
+
if (opts.json) {
|
|
46
|
+
console.log(JSON.stringify(b));
|
|
47
|
+
return;
|
|
59
48
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
console.log(`\n
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
49
|
+
const timing = b.timing || { ttfb: 0, domReady: 0, load: 0 };
|
|
50
|
+
// ── Page Info ──
|
|
51
|
+
console.log(`\n${brand('Inspecting')} ${bold(b.url || url)}`);
|
|
52
|
+
console.log(` ${muted('Title:')} ${b.title || '(none)'}`);
|
|
53
|
+
console.log(` ${muted('Elements:')} ${b.elementCount || 0}`);
|
|
54
|
+
console.log(` ${muted('Page weight:')} ${info(formatSize(b.totalBytes || 0))}`);
|
|
55
|
+
// ── Timing ──
|
|
56
|
+
console.log(`\n ${bold('Timing:')}`);
|
|
57
|
+
console.log(` ${muted('TTFB:')} ${timing.ttfb}ms`);
|
|
58
|
+
console.log(` ${muted('DOM ready:')} ${timing.domReady}ms`);
|
|
59
|
+
console.log(` ${muted('Load:')} ${timing.load}ms`);
|
|
60
|
+
if (showAll && b.lcp) {
|
|
61
|
+
console.log(` LCP: ${b.lcp.time}ms (${b.lcp.element}${b.lcp.url ? ' ' + shortUrl(b.lcp.url, truncate) : ''})`);
|
|
69
62
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
for (const r of b.renderBlocking) {
|
|
76
|
-
console.log(` ${shortUrl(r, truncate)}`);
|
|
63
|
+
// ── Console ──
|
|
64
|
+
if (b.console?.length > 0) {
|
|
65
|
+
console.log(`\n ${bold('Console')} ${muted(`(${b.console.length})`)}:`);
|
|
66
|
+
for (const line of b.console) {
|
|
67
|
+
console.log(` ${warning(line)}`);
|
|
77
68
|
}
|
|
78
69
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
70
|
+
else {
|
|
71
|
+
console.log(`\n ${bold('Console:')} ${muted('(clean)')}`);
|
|
72
|
+
}
|
|
73
|
+
// ── Failed Resources ──
|
|
74
|
+
if (b.failedResources?.length > 0) {
|
|
75
|
+
console.log(`\n ${clrError(`Failed resources (${b.failedResources.length}):`)}`);
|
|
76
|
+
for (const r of b.failedResources) {
|
|
77
|
+
console.log(` ${clrError(r)}`);
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
|
-
// ──
|
|
87
|
-
if (b.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
// ── Layout (horizontal overflow) ──
|
|
81
|
+
if (b.overflow) {
|
|
82
|
+
if (b.overflow.overflowX) {
|
|
83
|
+
console.log(`\n ${clrError(`Horizontal overflow: +${b.overflow.amount}px`)} ${muted(`(content ${b.overflow.scrollWidth}px vs viewport ${b.overflow.clientWidth}px)`)}`);
|
|
84
|
+
if (showAll && b.overflow.culprits.length > 0) {
|
|
85
|
+
console.log(` ${muted('Overflowing elements:')}`);
|
|
86
|
+
for (const c of b.overflow.culprits) {
|
|
87
|
+
const sel = c.cls ? `${c.tag}.${c.cls.split(/\s+/)[0]}` : c.tag;
|
|
88
|
+
console.log(` ${sel} ${muted(`(right ${c.right}px, width ${c.width}px)`)}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (b.overflow.culprits.length > 0) {
|
|
92
|
+
console.log(` ${muted(`${b.overflow.culprits.length} overflowing element(s) - use --all to list`)}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
console.log(`\n ${bold('Layout:')} ${muted('no horizontal overflow')}`);
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
if (showAll) {
|
|
100
|
+
// ── Render Blocking ──
|
|
101
|
+
if (b.renderBlocking?.length > 0) {
|
|
102
|
+
console.log(`\n ${warning(`Render-blocking (${b.renderBlocking.length}):`)}`);
|
|
103
|
+
for (const r of b.renderBlocking) {
|
|
104
|
+
console.log(` ${shortUrl(r, truncate)}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// ── Large Resources ──
|
|
108
|
+
if (b.largeResources?.length > 0) {
|
|
109
|
+
console.log(`\n ${warning(`Large resources >100KB (${b.largeResources.length}):`)}`);
|
|
110
|
+
for (const r of b.largeResources) {
|
|
111
|
+
console.log(` ${info(formatSize(r.size).padEnd(10))} ${muted(r.type.padEnd(8))} ${shortUrl(r.url, truncate)}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// ── Oversized Images ──
|
|
115
|
+
if (b.oversizedImages?.length > 0) {
|
|
116
|
+
console.log(`\n ${warning(`Oversized images (${b.oversizedImages.length}):`)}`);
|
|
117
|
+
for (const img of b.oversizedImages) {
|
|
118
|
+
console.log(` ${img.natural} served, ${img.displayed} displayed - ${shortUrl(img.src, truncate)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
console.log('');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
96
125
|
//# sourceMappingURL=page-inspect.js.map
|
|
@@ -91,7 +91,7 @@ function splitCsv(values) {
|
|
|
91
91
|
function appendOption(value, previous = []) {
|
|
92
92
|
return [...previous, value];
|
|
93
93
|
}
|
|
94
|
-
export const pageScreenshotCommand = new Command('
|
|
94
|
+
export const pageScreenshotCommand = new Command('screenshot')
|
|
95
95
|
.description('Screenshot a web page')
|
|
96
96
|
.argument('<url>', 'URL to screenshot')
|
|
97
97
|
.option('--post-load-delay <ms>', 'Delay after DOMContentLoaded before capture, in ms', '1000')
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { pageInspectCommand } from './page-inspect.js';
|
|
3
|
+
import { pageScreenshotCommand } from './page-screenshot.js';
|
|
4
|
+
import { pageEvalCommand } from './page-eval.js';
|
|
5
|
+
// Parent namespace grouping the page/browser diagnostics under one command:
|
|
6
|
+
// gipity page inspect | eval | screenshot
|
|
7
|
+
// Each subcommand is canonical for its capability; the namespace keeps the
|
|
8
|
+
// top-level surface lean and makes the siblings discoverable via `page --help`.
|
|
9
|
+
export const pageCommand = new Command('page')
|
|
10
|
+
.description('Inspect, evaluate, and screenshot web pages (page inspect | eval | screenshot)')
|
|
11
|
+
.addCommand(pageInspectCommand)
|
|
12
|
+
.addCommand(pageEvalCommand)
|
|
13
|
+
.addCommand(pageScreenshotCommand);
|
|
14
|
+
// No subcommand → show help instead of commander's terse error.
|
|
15
|
+
pageCommand.action(() => {
|
|
16
|
+
pageCommand.help();
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=page.js.map
|
package/dist/commands/project.js
CHANGED
|
@@ -3,10 +3,7 @@ import { get, post, put, del } from '../api.js';
|
|
|
3
3
|
import { requireConfig } from '../config.js';
|
|
4
4
|
import { success, error as clrError, muted, bold } from '../colors.js';
|
|
5
5
|
import { run, printList, printResult } from '../helpers/index.js';
|
|
6
|
-
|
|
7
|
-
.description('Manage workflows')
|
|
8
|
-
.option('--json', 'Output as JSON')
|
|
9
|
-
.action((opts) => run('Workflow', async () => {
|
|
6
|
+
async function listWorkflows(opts) {
|
|
10
7
|
const res = await get('/workflows');
|
|
11
8
|
if (opts.json) {
|
|
12
9
|
console.log(JSON.stringify(res));
|
|
@@ -23,7 +20,16 @@ export const workflowCommand = new Command('workflow')
|
|
|
23
20
|
const line = `${bold(w.name)} [${statusText}] ${muted(w.trigger_type)}${cron}${proj}`;
|
|
24
21
|
return w.description ? `${line}\n ${muted(w.description)}` : line;
|
|
25
22
|
});
|
|
26
|
-
}
|
|
23
|
+
}
|
|
24
|
+
export const workflowCommand = new Command('workflow')
|
|
25
|
+
.description('Manage workflows')
|
|
26
|
+
.option('--json', 'Output as JSON')
|
|
27
|
+
.action((opts) => run('Workflow', () => listWorkflows(opts)));
|
|
28
|
+
workflowCommand
|
|
29
|
+
.command('list')
|
|
30
|
+
.description('List workflows')
|
|
31
|
+
.option('--json', 'Output as JSON')
|
|
32
|
+
.action((opts) => run('List', () => listWorkflows(opts)));
|
|
27
33
|
workflowCommand
|
|
28
34
|
.command('info <name>')
|
|
29
35
|
.description('Show workflow details')
|
|
@@ -71,7 +77,9 @@ workflowCommand
|
|
|
71
77
|
? `${((new Date(r.completed_at).getTime() - new Date(r.started_at).getTime()) / 1000).toFixed(1)}s`
|
|
72
78
|
: 'running';
|
|
73
79
|
const statusColor = r.status === 'completed' ? success : r.status === 'failed' ? clrError : muted;
|
|
74
|
-
|
|
80
|
+
const line = `${muted(r.short_guid)} ${statusColor(r.status)} ${dur} ${r.total_tokens} tokens ${muted(new Date(r.started_at).toLocaleString())}`;
|
|
81
|
+
// Surface why a run failed inline so you don't have to hit the REST API.
|
|
82
|
+
return r.error_message ? `${line}\n ${clrError(r.error_message)}` : line;
|
|
75
83
|
});
|
|
76
84
|
}));
|
|
77
85
|
workflowCommand
|
|
@@ -80,8 +88,12 @@ workflowCommand
|
|
|
80
88
|
.option('--json', 'Output as JSON')
|
|
81
89
|
.action((name, opts) => run('Enable', async () => {
|
|
82
90
|
const wf = await resolveWorkflow(name);
|
|
83
|
-
await put(`/workflows/${wf.short_guid}`, { is_active: true });
|
|
84
|
-
|
|
91
|
+
const res = await put(`/workflows/${wf.short_guid}`, { is_active: true });
|
|
92
|
+
if (!res.data?.is_active) {
|
|
93
|
+
console.error(clrError(`Workflow "${wf.name}" is still inactive after enable — not enabled.`));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
printResult(`Enabled "${wf.name}".`, opts, { enabled: wf.name, is_active: true });
|
|
85
97
|
}));
|
|
86
98
|
workflowCommand
|
|
87
99
|
.command('disable <name>')
|
|
@@ -89,8 +101,12 @@ workflowCommand
|
|
|
89
101
|
.option('--json', 'Output as JSON')
|
|
90
102
|
.action((name, opts) => run('Disable', async () => {
|
|
91
103
|
const wf = await resolveWorkflow(name);
|
|
92
|
-
await put(`/workflows/${wf.short_guid}`, { is_active: false });
|
|
93
|
-
|
|
104
|
+
const res = await put(`/workflows/${wf.short_guid}`, { is_active: false });
|
|
105
|
+
if (res.data?.is_active) {
|
|
106
|
+
console.error(clrError(`Workflow "${wf.name}" is still active after disable — not disabled.`));
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
printResult(`Disabled "${wf.name}".`, opts, { disabled: wf.name, is_active: false });
|
|
94
110
|
}));
|
|
95
111
|
workflowCommand
|
|
96
112
|
.command('create')
|
|
@@ -132,15 +148,46 @@ workflowCommand
|
|
|
132
148
|
.action((name, opts) => run('Delete', async () => {
|
|
133
149
|
const wf = await resolveWorkflow(name);
|
|
134
150
|
await del(`/workflows/${wf.short_guid}`);
|
|
135
|
-
|
|
151
|
+
// Delete is a soft-delete (is_active → 0). Verify the targeted record
|
|
152
|
+
// actually went inactive rather than trusting the request was accepted.
|
|
153
|
+
const after = await get(`/workflows/${wf.short_guid}`);
|
|
154
|
+
if (after.data?.is_active) {
|
|
155
|
+
console.error(clrError(`Workflow "${wf.name}" (${wf.short_guid}) is still active — delete had no effect.`));
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
printResult(`Deleted "${wf.name}".`, opts, { deleted: wf.name, short_guid: wf.short_guid });
|
|
136
159
|
}));
|
|
160
|
+
// Resolve a workflow by name within the linked project (like `gipity fn`), or
|
|
161
|
+
// by short_guid anywhere. Names are unique per active project workflow (DB
|
|
162
|
+
// constraint), so a bare name in this project is unambiguous; the same name in
|
|
163
|
+
// another project is a different workflow and simply isn't matched here.
|
|
137
164
|
async function resolveWorkflow(name) {
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
165
|
+
const { projectGuid } = requireConfig();
|
|
166
|
+
const res = await get(`/projects/${projectGuid}/workflows`);
|
|
167
|
+
const list = res.data ?? [];
|
|
168
|
+
// Exact short_guid match wins — unambiguous override.
|
|
169
|
+
const byGuid = list.find(w => w.short_guid === name);
|
|
170
|
+
if (byGuid)
|
|
171
|
+
return byGuid;
|
|
172
|
+
const byName = list.filter(w => w.name === name);
|
|
173
|
+
if (byName.length === 0) {
|
|
174
|
+
// Fall back to a global short_guid lookup (e.g. account-level workflows).
|
|
175
|
+
const all = await get('/workflows');
|
|
176
|
+
const global = (all.data ?? []).find(w => w.short_guid === name);
|
|
177
|
+
if (global)
|
|
178
|
+
return global;
|
|
179
|
+
console.error(clrError(`Workflow "${name}" not found in this project.`));
|
|
142
180
|
process.exit(1);
|
|
143
181
|
}
|
|
144
|
-
|
|
182
|
+
if (byName.length === 1)
|
|
183
|
+
return byName[0];
|
|
184
|
+
// More than one (an active + soft-deleted carrying the same name): prefer the
|
|
185
|
+
// active one; refuse if still ambiguous.
|
|
186
|
+
const active = byName.filter(w => w.is_active);
|
|
187
|
+
if (active.length === 1)
|
|
188
|
+
return active[0];
|
|
189
|
+
console.error(clrError(`${byName.length} workflows named "${name}" in this project — pass a short_guid:\n` +
|
|
190
|
+
byName.map(w => ` ${w.short_guid}${w.is_active ? '' : ' (inactive)'}`).join('\n')));
|
|
191
|
+
process.exit(1);
|
|
145
192
|
}
|
|
146
193
|
//# sourceMappingURL=workflow.js.map
|