@ttctl/cli 0.0.0 → 0.1.0-rc.1
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 +44 -9
- package/dist/commands/applications/index.d.ts +21 -0
- package/dist/commands/applications/index.d.ts.map +1 -0
- package/dist/commands/applications/index.js +87 -0
- package/dist/commands/applications/index.js.map +1 -0
- package/dist/commands/applications/list.d.ts +55 -0
- package/dist/commands/applications/list.d.ts.map +1 -0
- package/dist/commands/applications/list.js +106 -0
- package/dist/commands/applications/list.js.map +1 -0
- package/dist/commands/applications/shared.d.ts +14 -0
- package/dist/commands/applications/shared.d.ts.map +1 -0
- package/dist/commands/applications/shared.js +19 -0
- package/dist/commands/applications/shared.js.map +1 -0
- package/dist/commands/applications/show.d.ts +51 -0
- package/dist/commands/applications/show.d.ts.map +1 -0
- package/dist/commands/applications/show.js +154 -0
- package/dist/commands/applications/show.js.map +1 -0
- package/dist/commands/applications/stats.d.ts +42 -0
- package/dist/commands/applications/stats.d.ts.map +1 -0
- package/dist/commands/applications/stats.js +69 -0
- package/dist/commands/applications/stats.js.map +1 -0
- package/dist/commands/auth/index.d.ts +17 -0
- package/dist/commands/auth/index.d.ts.map +1 -0
- package/dist/commands/auth/index.js +69 -0
- package/dist/commands/auth/index.js.map +1 -0
- package/dist/commands/auth/init.d.ts +98 -0
- package/dist/commands/auth/init.d.ts.map +1 -0
- package/dist/commands/auth/init.js +387 -0
- package/dist/commands/auth/init.js.map +1 -0
- package/dist/commands/auth/signin.d.ts +81 -0
- package/dist/commands/auth/signin.d.ts.map +1 -0
- package/dist/commands/auth/signin.js +145 -0
- package/dist/commands/auth/signin.js.map +1 -0
- package/dist/commands/auth/signout.d.ts +133 -0
- package/dist/commands/auth/signout.d.ts.map +1 -0
- package/dist/commands/auth/signout.js +172 -0
- package/dist/commands/auth/signout.js.map +1 -0
- package/dist/commands/auth/status.d.ts +62 -0
- package/dist/commands/auth/status.d.ts.map +1 -0
- package/dist/commands/auth/status.js +98 -0
- package/dist/commands/auth/status.js.map +1 -0
- package/dist/commands/availability/allocated-hours.d.ts +27 -0
- package/dist/commands/availability/allocated-hours.d.ts.map +1 -0
- package/dist/commands/availability/allocated-hours.js +61 -0
- package/dist/commands/availability/allocated-hours.js.map +1 -0
- package/dist/commands/availability/index.d.ts +30 -0
- package/dist/commands/availability/index.d.ts.map +1 -0
- package/dist/commands/availability/index.js +124 -0
- package/dist/commands/availability/index.js.map +1 -0
- package/dist/commands/availability/shared.d.ts +11 -0
- package/dist/commands/availability/shared.d.ts.map +1 -0
- package/dist/commands/availability/shared.js +30 -0
- package/dist/commands/availability/shared.js.map +1 -0
- package/dist/commands/availability/show.d.ts +32 -0
- package/dist/commands/availability/show.d.ts.map +1 -0
- package/dist/commands/availability/show.js +86 -0
- package/dist/commands/availability/show.js.map +1 -0
- package/dist/commands/availability/working-hours.d.ts +53 -0
- package/dist/commands/availability/working-hours.d.ts.map +1 -0
- package/dist/commands/availability/working-hours.js +151 -0
- package/dist/commands/availability/working-hours.js.map +1 -0
- package/dist/commands/contracts/index.d.ts +69 -0
- package/dist/commands/contracts/index.d.ts.map +1 -0
- package/dist/commands/contracts/index.js +198 -0
- package/dist/commands/contracts/index.js.map +1 -0
- package/dist/commands/engagements/breaks.d.ts +81 -0
- package/dist/commands/engagements/breaks.d.ts.map +1 -0
- package/dist/commands/engagements/breaks.js +229 -0
- package/dist/commands/engagements/breaks.js.map +1 -0
- package/dist/commands/engagements/index.d.ts +29 -0
- package/dist/commands/engagements/index.d.ts.map +1 -0
- package/dist/commands/engagements/index.js +172 -0
- package/dist/commands/engagements/index.js.map +1 -0
- package/dist/commands/engagements/list.d.ts +49 -0
- package/dist/commands/engagements/list.d.ts.map +1 -0
- package/dist/commands/engagements/list.js +95 -0
- package/dist/commands/engagements/list.js.map +1 -0
- package/dist/commands/engagements/shared.d.ts +10 -0
- package/dist/commands/engagements/shared.d.ts.map +1 -0
- package/dist/commands/engagements/shared.js +31 -0
- package/dist/commands/engagements/shared.js.map +1 -0
- package/dist/commands/engagements/show.d.ts +19 -0
- package/dist/commands/engagements/show.d.ts.map +1 -0
- package/dist/commands/engagements/show.js +150 -0
- package/dist/commands/engagements/show.js.map +1 -0
- package/dist/commands/engagements/stats.d.ts +24 -0
- package/dist/commands/engagements/stats.d.ts.map +1 -0
- package/dist/commands/engagements/stats.js +51 -0
- package/dist/commands/engagements/stats.js.map +1 -0
- package/dist/commands/jobs/index.d.ts +49 -0
- package/dist/commands/jobs/index.d.ts.map +1 -0
- package/dist/commands/jobs/index.js +304 -0
- package/dist/commands/jobs/index.js.map +1 -0
- package/dist/commands/jobs/interest.d.ts +65 -0
- package/dist/commands/jobs/interest.d.ts.map +1 -0
- package/dist/commands/jobs/interest.js +172 -0
- package/dist/commands/jobs/interest.js.map +1 -0
- package/dist/commands/jobs/list.d.ts +81 -0
- package/dist/commands/jobs/list.d.ts.map +1 -0
- package/dist/commands/jobs/list.js +157 -0
- package/dist/commands/jobs/list.js.map +1 -0
- package/dist/commands/jobs/search.d.ts +71 -0
- package/dist/commands/jobs/search.d.ts.map +1 -0
- package/dist/commands/jobs/search.js +163 -0
- package/dist/commands/jobs/search.js.map +1 -0
- package/dist/commands/jobs/shared.d.ts +79 -0
- package/dist/commands/jobs/shared.d.ts.map +1 -0
- package/dist/commands/jobs/shared.js +133 -0
- package/dist/commands/jobs/shared.js.map +1 -0
- package/dist/commands/jobs/show.d.ts +20 -0
- package/dist/commands/jobs/show.d.ts.map +1 -0
- package/dist/commands/jobs/show.js +135 -0
- package/dist/commands/jobs/show.js.map +1 -0
- package/dist/commands/payments/index.d.ts +34 -0
- package/dist/commands/payments/index.d.ts.map +1 -0
- package/dist/commands/payments/index.js +160 -0
- package/dist/commands/payments/index.js.map +1 -0
- package/dist/commands/payments/methods.d.ts +17 -0
- package/dist/commands/payments/methods.d.ts.map +1 -0
- package/dist/commands/payments/methods.js +79 -0
- package/dist/commands/payments/methods.js.map +1 -0
- package/dist/commands/payments/payouts.d.ts +44 -0
- package/dist/commands/payments/payouts.d.ts.map +1 -0
- package/dist/commands/payments/payouts.js +147 -0
- package/dist/commands/payments/payouts.js.map +1 -0
- package/dist/commands/payments/rate.d.ts +48 -0
- package/dist/commands/payments/rate.d.ts.map +1 -0
- package/dist/commands/payments/rate.js +229 -0
- package/dist/commands/payments/rate.js.map +1 -0
- package/dist/commands/payments/shared.d.ts +10 -0
- package/dist/commands/payments/shared.d.ts.map +1 -0
- package/dist/commands/payments/shared.js +27 -0
- package/dist/commands/payments/shared.js.map +1 -0
- package/dist/commands/profile/basic/index.d.ts +18 -0
- package/dist/commands/profile/basic/index.d.ts.map +1 -0
- package/dist/commands/profile/basic/index.js +79 -0
- package/dist/commands/profile/basic/index.js.map +1 -0
- package/dist/commands/profile/basic/photo-show.d.ts +28 -0
- package/dist/commands/profile/basic/photo-show.d.ts.map +1 -0
- package/dist/commands/profile/basic/photo-show.js +112 -0
- package/dist/commands/profile/basic/photo-show.js.map +1 -0
- package/dist/commands/profile/basic/photo-upload.d.ts +10 -0
- package/dist/commands/profile/basic/photo-upload.d.ts.map +1 -0
- package/dist/commands/profile/basic/photo-upload.js +61 -0
- package/dist/commands/profile/basic/photo-upload.js.map +1 -0
- package/dist/commands/profile/basic/set.d.ts +54 -0
- package/dist/commands/profile/basic/set.d.ts.map +1 -0
- package/dist/commands/profile/basic/set.js +174 -0
- package/dist/commands/profile/basic/set.js.map +1 -0
- package/dist/commands/profile/basic/show.d.ts +95 -0
- package/dist/commands/profile/basic/show.d.ts.map +1 -0
- package/dist/commands/profile/basic/show.js +310 -0
- package/dist/commands/profile/basic/show.js.map +1 -0
- package/dist/commands/profile/certifications/index.d.ts +31 -0
- package/dist/commands/profile/certifications/index.d.ts.map +1 -0
- package/dist/commands/profile/certifications/index.js +298 -0
- package/dist/commands/profile/certifications/index.js.map +1 -0
- package/dist/commands/profile/education/index.d.ts +28 -0
- package/dist/commands/profile/education/index.d.ts.map +1 -0
- package/dist/commands/profile/education/index.js +287 -0
- package/dist/commands/profile/education/index.js.map +1 -0
- package/dist/commands/profile/employment/index.d.ts +40 -0
- package/dist/commands/profile/employment/index.d.ts.map +1 -0
- package/dist/commands/profile/employment/index.js +364 -0
- package/dist/commands/profile/employment/index.js.map +1 -0
- package/dist/commands/profile/external/_shared.d.ts +35 -0
- package/dist/commands/profile/external/_shared.d.ts.map +1 -0
- package/dist/commands/profile/external/_shared.js +59 -0
- package/dist/commands/profile/external/_shared.js.map +1 -0
- package/dist/commands/profile/external/advanced-wizard-show.d.ts +15 -0
- package/dist/commands/profile/external/advanced-wizard-show.d.ts.map +1 -0
- package/dist/commands/profile/external/advanced-wizard-show.js +82 -0
- package/dist/commands/profile/external/advanced-wizard-show.js.map +1 -0
- package/dist/commands/profile/external/custom-requirements-set.d.ts +32 -0
- package/dist/commands/profile/external/custom-requirements-set.d.ts.map +1 -0
- package/dist/commands/profile/external/custom-requirements-set.js +116 -0
- package/dist/commands/profile/external/custom-requirements-set.js.map +1 -0
- package/dist/commands/profile/external/custom-requirements-show.d.ts +16 -0
- package/dist/commands/profile/external/custom-requirements-show.d.ts.map +1 -0
- package/dist/commands/profile/external/custom-requirements-show.js +84 -0
- package/dist/commands/profile/external/custom-requirements-show.js.map +1 -0
- package/dist/commands/profile/external/index.d.ts +20 -0
- package/dist/commands/profile/external/index.d.ts.map +1 -0
- package/dist/commands/profile/external/index.js +102 -0
- package/dist/commands/profile/external/index.js.map +1 -0
- package/dist/commands/profile/external/readiness.d.ts +15 -0
- package/dist/commands/profile/external/readiness.d.ts.map +1 -0
- package/dist/commands/profile/external/readiness.js +104 -0
- package/dist/commands/profile/external/readiness.js.map +1 -0
- package/dist/commands/profile/external/recommendations.d.ts +17 -0
- package/dist/commands/profile/external/recommendations.d.ts.map +1 -0
- package/dist/commands/profile/external/recommendations.js +97 -0
- package/dist/commands/profile/external/recommendations.js.map +1 -0
- package/dist/commands/profile/external/update.d.ts +32 -0
- package/dist/commands/profile/external/update.d.ts.map +1 -0
- package/dist/commands/profile/external/update.js +118 -0
- package/dist/commands/profile/external/update.js.map +1 -0
- package/dist/commands/profile/index.d.ts +16 -0
- package/dist/commands/profile/index.d.ts.map +1 -0
- package/dist/commands/profile/index.js +81 -0
- package/dist/commands/profile/index.js.map +1 -0
- package/dist/commands/profile/industries/index.d.ts +36 -0
- package/dist/commands/profile/industries/index.d.ts.map +1 -0
- package/dist/commands/profile/industries/index.js +230 -0
- package/dist/commands/profile/industries/index.js.map +1 -0
- package/dist/commands/profile/portfolio/add.d.ts +43 -0
- package/dist/commands/profile/portfolio/add.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/add.js +181 -0
- package/dist/commands/profile/portfolio/add.js.map +1 -0
- package/dist/commands/profile/portfolio/highlight.d.ts +11 -0
- package/dist/commands/profile/portfolio/highlight.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/highlight.js +31 -0
- package/dist/commands/profile/portfolio/highlight.js.map +1 -0
- package/dist/commands/profile/portfolio/index.d.ts +16 -0
- package/dist/commands/profile/portfolio/index.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/index.js +121 -0
- package/dist/commands/profile/portfolio/index.js.map +1 -0
- package/dist/commands/profile/portfolio/list.d.ts +83 -0
- package/dist/commands/profile/portfolio/list.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/list.js +189 -0
- package/dist/commands/profile/portfolio/list.js.map +1 -0
- package/dist/commands/profile/portfolio/remove.d.ts +9 -0
- package/dist/commands/profile/portfolio/remove.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/remove.js +24 -0
- package/dist/commands/profile/portfolio/remove.js.map +1 -0
- package/dist/commands/profile/portfolio/reorder.d.ts +17 -0
- package/dist/commands/profile/portfolio/reorder.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/reorder.js +135 -0
- package/dist/commands/profile/portfolio/reorder.js.map +1 -0
- package/dist/commands/profile/portfolio/shared.d.ts +8 -0
- package/dist/commands/profile/portfolio/shared.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/shared.js +10 -0
- package/dist/commands/profile/portfolio/shared.js.map +1 -0
- package/dist/commands/profile/portfolio/update.d.ts +18 -0
- package/dist/commands/profile/portfolio/update.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/update.js +77 -0
- package/dist/commands/profile/portfolio/update.js.map +1 -0
- package/dist/commands/profile/portfolio/upload.d.ts +8 -0
- package/dist/commands/profile/portfolio/upload.d.ts.map +1 -0
- package/dist/commands/profile/portfolio/upload.js +131 -0
- package/dist/commands/profile/portfolio/upload.js.map +1 -0
- package/dist/commands/profile/resume/cancel-upload.d.ts +9 -0
- package/dist/commands/profile/resume/cancel-upload.d.ts.map +1 -0
- package/dist/commands/profile/resume/cancel-upload.js +30 -0
- package/dist/commands/profile/resume/cancel-upload.js.map +1 -0
- package/dist/commands/profile/resume/index.d.ts +15 -0
- package/dist/commands/profile/resume/index.d.ts.map +1 -0
- package/dist/commands/profile/resume/index.js +42 -0
- package/dist/commands/profile/resume/index.js.map +1 -0
- package/dist/commands/profile/resume/upload.d.ts +16 -0
- package/dist/commands/profile/resume/upload.d.ts.map +1 -0
- package/dist/commands/profile/resume/upload.js +65 -0
- package/dist/commands/profile/resume/upload.js.map +1 -0
- package/dist/commands/profile/reviews/_shared.d.ts +9 -0
- package/dist/commands/profile/reviews/_shared.d.ts.map +1 -0
- package/dist/commands/profile/reviews/_shared.js +15 -0
- package/dist/commands/profile/reviews/_shared.js.map +1 -0
- package/dist/commands/profile/reviews/approve-item.d.ts +30 -0
- package/dist/commands/profile/reviews/approve-item.d.ts.map +1 -0
- package/dist/commands/profile/reviews/approve-item.js +82 -0
- package/dist/commands/profile/reviews/approve-item.js.map +1 -0
- package/dist/commands/profile/reviews/approve-section.d.ts +15 -0
- package/dist/commands/profile/reviews/approve-section.d.ts.map +1 -0
- package/dist/commands/profile/reviews/approve-section.js +67 -0
- package/dist/commands/profile/reviews/approve-section.js.map +1 -0
- package/dist/commands/profile/reviews/index.d.ts +19 -0
- package/dist/commands/profile/reviews/index.d.ts.map +1 -0
- package/dist/commands/profile/reviews/index.js +71 -0
- package/dist/commands/profile/reviews/index.js.map +1 -0
- package/dist/commands/profile/reviews/list.d.ts +17 -0
- package/dist/commands/profile/reviews/list.d.ts.map +1 -0
- package/dist/commands/profile/reviews/list.js +96 -0
- package/dist/commands/profile/reviews/list.js.map +1 -0
- package/dist/commands/profile/reviews/submit-for-review.d.ts +16 -0
- package/dist/commands/profile/reviews/submit-for-review.d.ts.map +1 -0
- package/dist/commands/profile/reviews/submit-for-review.js +65 -0
- package/dist/commands/profile/reviews/submit-for-review.js.map +1 -0
- package/dist/commands/profile/shared.d.ts +46 -0
- package/dist/commands/profile/shared.d.ts.map +1 -0
- package/dist/commands/profile/shared.js +111 -0
- package/dist/commands/profile/shared.js.map +1 -0
- package/dist/commands/profile/skills/index.d.ts +29 -0
- package/dist/commands/profile/skills/index.d.ts.map +1 -0
- package/dist/commands/profile/skills/index.js +475 -0
- package/dist/commands/profile/skills/index.js.map +1 -0
- package/dist/commands/profile/visas/add.d.ts +19 -0
- package/dist/commands/profile/visas/add.d.ts.map +1 -0
- package/dist/commands/profile/visas/add.js +37 -0
- package/dist/commands/profile/visas/add.js.map +1 -0
- package/dist/commands/profile/visas/index.d.ts +13 -0
- package/dist/commands/profile/visas/index.d.ts.map +1 -0
- package/dist/commands/profile/visas/index.js +69 -0
- package/dist/commands/profile/visas/index.js.map +1 -0
- package/dist/commands/profile/visas/list.d.ts +40 -0
- package/dist/commands/profile/visas/list.d.ts.map +1 -0
- package/dist/commands/profile/visas/list.js +115 -0
- package/dist/commands/profile/visas/list.js.map +1 -0
- package/dist/commands/profile/visas/remove.d.ts +8 -0
- package/dist/commands/profile/visas/remove.d.ts.map +1 -0
- package/dist/commands/profile/visas/remove.js +23 -0
- package/dist/commands/profile/visas/remove.js.map +1 -0
- package/dist/commands/profile/visas/shared.d.ts +11 -0
- package/dist/commands/profile/visas/shared.d.ts.map +1 -0
- package/dist/commands/profile/visas/shared.js +16 -0
- package/dist/commands/profile/visas/shared.js.map +1 -0
- package/dist/commands/profile/visas/update.d.ts +13 -0
- package/dist/commands/profile/visas/update.d.ts.map +1 -0
- package/dist/commands/profile/visas/update.js +44 -0
- package/dist/commands/profile/visas/update.js.map +1 -0
- package/dist/commands/timesheet/index.d.ts +24 -0
- package/dist/commands/timesheet/index.d.ts.map +1 -0
- package/dist/commands/timesheet/index.js +98 -0
- package/dist/commands/timesheet/index.js.map +1 -0
- package/dist/commands/timesheet/list.d.ts +40 -0
- package/dist/commands/timesheet/list.d.ts.map +1 -0
- package/dist/commands/timesheet/list.js +79 -0
- package/dist/commands/timesheet/list.js.map +1 -0
- package/dist/commands/timesheet/shared.d.ts +10 -0
- package/dist/commands/timesheet/shared.d.ts.map +1 -0
- package/dist/commands/timesheet/shared.js +35 -0
- package/dist/commands/timesheet/shared.js.map +1 -0
- package/dist/commands/timesheet/show.d.ts +19 -0
- package/dist/commands/timesheet/show.d.ts.map +1 -0
- package/dist/commands/timesheet/show.js +109 -0
- package/dist/commands/timesheet/show.js.map +1 -0
- package/dist/commands/timesheet/submit.d.ts +50 -0
- package/dist/commands/timesheet/submit.d.ts.map +1 -0
- package/dist/commands/timesheet/submit.js +151 -0
- package/dist/commands/timesheet/submit.js.map +1 -0
- package/dist/crash-handlers.d.ts +67 -0
- package/dist/crash-handlers.d.ts.map +1 -0
- package/dist/crash-handlers.js +78 -0
- package/dist/crash-handlers.js.map +1 -0
- package/dist/errors.d.ts +45 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config-context.d.ts +41 -0
- package/dist/lib/config-context.d.ts.map +1 -0
- package/dist/lib/config-context.js +74 -0
- package/dist/lib/config-context.js.map +1 -0
- package/dist/lib/dry-run.d.ts +70 -0
- package/dist/lib/dry-run.d.ts.map +1 -0
- package/dist/lib/dry-run.js +114 -0
- package/dist/lib/dry-run.js.map +1 -0
- package/dist/lib/empty-state-cta.d.ts +63 -0
- package/dist/lib/empty-state-cta.d.ts.map +1 -0
- package/dist/lib/empty-state-cta.js +88 -0
- package/dist/lib/empty-state-cta.js.map +1 -0
- package/dist/lib/envelopes.d.ts +540 -0
- package/dist/lib/envelopes.d.ts.map +1 -0
- package/dist/lib/envelopes.js +598 -0
- package/dist/lib/envelopes.js.map +1 -0
- package/dist/lib/error-routing.d.ts +49 -0
- package/dist/lib/error-routing.d.ts.map +1 -0
- package/dist/lib/error-routing.js +72 -0
- package/dist/lib/error-routing.js.map +1 -0
- package/dist/lib/format-helpers.d.ts +65 -0
- package/dist/lib/format-helpers.d.ts.map +1 -0
- package/dist/lib/format-helpers.js +79 -0
- package/dist/lib/format-helpers.js.map +1 -0
- package/dist/lib/format-overrides.d.ts +81 -0
- package/dist/lib/format-overrides.d.ts.map +1 -0
- package/dist/lib/format-overrides.js +55 -0
- package/dist/lib/format-overrides.js.map +1 -0
- package/dist/lib/freetext.d.ts +83 -0
- package/dist/lib/freetext.d.ts.map +1 -0
- package/dist/lib/freetext.js +182 -0
- package/dist/lib/freetext.js.map +1 -0
- package/dist/lib/kill-switch-hook.d.ts +49 -0
- package/dist/lib/kill-switch-hook.d.ts.map +1 -0
- package/dist/lib/kill-switch-hook.js +34 -0
- package/dist/lib/kill-switch-hook.js.map +1 -0
- package/dist/lib/output.d.ts +173 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +177 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/pagination.d.ts +49 -0
- package/dist/lib/pagination.d.ts.map +1 -0
- package/dist/lib/pagination.js +36 -0
- package/dist/lib/pagination.js.map +1 -0
- package/dist/program.d.ts +80 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +273 -0
- package/dist/program.js.map +1 -0
- package/package.json +35 -13
- package/index.js +0 -7
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import * as p from "@clack/prompts";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { OP_REF_PATTERN_HINT, OP_REF_PATTERN_SOURCE, writeNewConfig } from "@ttctl/core";
|
|
10
|
+
/**
|
|
11
|
+
* Compiled `RegExp` for a 1Password item reference, constructed once at
|
|
12
|
+
* module load from the canonical {@link OP_REF_PATTERN_SOURCE} exported by
|
|
13
|
+
* `@ttctl/core`. Sharing the source string (rather than the compiled
|
|
14
|
+
* `RegExp`) keeps the CLI bundle free of Zod while guaranteeing the
|
|
15
|
+
* pattern stays in lock-step with `OnePasswordReferenceSchema`.
|
|
16
|
+
*/
|
|
17
|
+
const OP_REF_REGEX = new RegExp(OP_REF_PATTERN_SOURCE);
|
|
18
|
+
/**
|
|
19
|
+
* Email regex for Form B username validation. Permissive — matches what a
|
|
20
|
+
* Toptal email address looks like without enforcing RFC-5321 strictness.
|
|
21
|
+
* Form B is a discouraged path; the EmailPasswordSignIn mutation will
|
|
22
|
+
* reject malformed values at signin time.
|
|
23
|
+
*/
|
|
24
|
+
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
25
|
+
/**
|
|
26
|
+
* Shape of `op vault list --format json` output (subset). The op CLI
|
|
27
|
+
* returns more fields per vault; we only consume `id` and `name`.
|
|
28
|
+
*/
|
|
29
|
+
const OpVaultListSchema = z.array(z.object({
|
|
30
|
+
id: z.string(),
|
|
31
|
+
name: z.string(),
|
|
32
|
+
}));
|
|
33
|
+
/**
|
|
34
|
+
* Shape of `op item list --vault <V> --categories Login --format json`
|
|
35
|
+
* output (subset). The op CLI returns more fields per item; we only
|
|
36
|
+
* consume `id` and `title`.
|
|
37
|
+
*/
|
|
38
|
+
const OpItemListSchema = z.array(z.object({
|
|
39
|
+
id: z.string(),
|
|
40
|
+
title: z.string(),
|
|
41
|
+
}));
|
|
42
|
+
/**
|
|
43
|
+
* Probe whether the `op` CLI is installed and reachable on PATH. Light
|
|
44
|
+
* `op --version` invocation — fails fast on `ENOENT` (not installed) and
|
|
45
|
+
* any other launch failure (signed-out, broken install, etc). Output is
|
|
46
|
+
* discarded; the only signal is whether the call returned successfully.
|
|
47
|
+
*/
|
|
48
|
+
function detectOpCli() {
|
|
49
|
+
try {
|
|
50
|
+
execFileSync("op", ["--version"], { stdio: ["ignore", "ignore", "ignore"] });
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Shell out to `op vault list --format json`. Returns the parsed,
|
|
59
|
+
* zod-validated list; throws on any failure (non-zero exit, parse
|
|
60
|
+
* failure, schema mismatch). Caller should catch and fall back to
|
|
61
|
+
* freeform prompt with a stderr warning.
|
|
62
|
+
*/
|
|
63
|
+
function listOpVaults() {
|
|
64
|
+
const raw = execFileSync("op", ["vault", "list", "--format", "json"], {
|
|
65
|
+
encoding: "utf8",
|
|
66
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
67
|
+
});
|
|
68
|
+
const parsedJson = JSON.parse(raw);
|
|
69
|
+
return OpVaultListSchema.parse(parsedJson);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Shell out to `op item list --vault <vault> --categories Login --format json`.
|
|
73
|
+
* Filters server-side to LOGIN-category items so the picker only shows
|
|
74
|
+
* relevant candidates. Returns parsed + zod-validated list; throws on
|
|
75
|
+
* failure (caller falls back to freeform).
|
|
76
|
+
*/
|
|
77
|
+
function listOpItems(vault) {
|
|
78
|
+
const raw = execFileSync("op", ["item", "list", "--vault", vault, "--categories", "Login", "--format", "json"], {
|
|
79
|
+
encoding: "utf8",
|
|
80
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
81
|
+
});
|
|
82
|
+
const parsedJson = JSON.parse(raw);
|
|
83
|
+
return OpItemListSchema.parse(parsedJson);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Map an `AuthInitResult` to a process exit code.
|
|
87
|
+
*
|
|
88
|
+
* - `written` → 0 (success)
|
|
89
|
+
* - `refused`/anything → 1 (non-TTY, exists-without-force, cancelled)
|
|
90
|
+
* - `error` → 1 (any unexpected failure)
|
|
91
|
+
*
|
|
92
|
+
* The cancelled / refused-form-B paths are intentionally non-zero — the
|
|
93
|
+
* shell convention is "exit 0 only on success." A user who hits Ctrl-C
|
|
94
|
+
* mid-prompt has not bootstrapped a config; subsequent commands assuming
|
|
95
|
+
* one exists would fail, so signaling success here would mislead scripts.
|
|
96
|
+
*/
|
|
97
|
+
export function exitCodeForInitResult(result) {
|
|
98
|
+
return result.status === "written" ? 0 : 1;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Render an `AuthInitResult` for stdout/stderr. Written → confirmation on
|
|
102
|
+
* stdout naming the path AND the form chosen (per AC). Refusals + errors
|
|
103
|
+
* → message on stderr.
|
|
104
|
+
*/
|
|
105
|
+
export function formatInitOutput(result) {
|
|
106
|
+
if (result.status === "written") {
|
|
107
|
+
const formLabel = result.form === "A" ? "1Password reference" : "literal credentials";
|
|
108
|
+
return `Wrote config to ${result.path} (form ${result.form}: ${formLabel})`;
|
|
109
|
+
}
|
|
110
|
+
return result.message;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Determine whether the current process has an interactive TTY on stdin.
|
|
114
|
+
* `@clack/prompts` produces undefined behavior when piped; we refuse
|
|
115
|
+
* cleanly BEFORE any prompt runs (FR-3.10 / non-TTY refusal AC).
|
|
116
|
+
*
|
|
117
|
+
* Exposed for unit tests that can't trivially set the TTY bit on stdin —
|
|
118
|
+
* tests stub this function to assert both branches deterministically.
|
|
119
|
+
*/
|
|
120
|
+
export function isStdinTty() {
|
|
121
|
+
// Node typings declare `process.stdin.isTTY?: true` — TS narrows the
|
|
122
|
+
// value to `true | undefined` and ESLint's
|
|
123
|
+
// `no-unnecessary-boolean-literal-compare` would object to `=== true`.
|
|
124
|
+
// Coercing through `unknown` lets us perform the strict equality (the
|
|
125
|
+
// ONLY check that's safe under runtime test mocks that may set the
|
|
126
|
+
// property to literal `false`) without tripping the lint rule.
|
|
127
|
+
return process.stdin.isTTY === true;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Default op CLI interface — shells out via `execFileSync`. Tests inject
|
|
131
|
+
* an alternative implementation via the second argument to `runAuthInit`.
|
|
132
|
+
*/
|
|
133
|
+
export const defaultOpCli = {
|
|
134
|
+
detect: detectOpCli,
|
|
135
|
+
listVaults: listOpVaults,
|
|
136
|
+
listItems: listOpItems,
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Resolve the target output path:
|
|
140
|
+
* - Explicit `--config <path>` → used verbatim
|
|
141
|
+
* - Otherwise → `~/.ttctl.yaml` (POSIX home dotfile, matches the
|
|
142
|
+
* resolution chain's only fallback)
|
|
143
|
+
*
|
|
144
|
+
* Parent directories are created by `writeNewConfig` (via `mkdir -p`); no
|
|
145
|
+
* pre-existence check on the parent.
|
|
146
|
+
*/
|
|
147
|
+
function resolveTargetPath(options) {
|
|
148
|
+
if (options.config !== undefined)
|
|
149
|
+
return options.config;
|
|
150
|
+
return join(homedir(), ".ttctl.yaml");
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Compose the YAML content for Form A (1Password reference). Quoted op://
|
|
154
|
+
* string preserves the canonical scalar style and disambiguates the value
|
|
155
|
+
* from any future YAML grammar expansion.
|
|
156
|
+
*/
|
|
157
|
+
function composeFormAYaml(ref) {
|
|
158
|
+
return `auth:\n credentials: "${ref}"\n`;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Compose the YAML content for Form B (literal credentials). `username`
|
|
162
|
+
* and `password` are double-quoted to keep YAML's special-character
|
|
163
|
+
* grammar from interfering with anything that might appear in a real
|
|
164
|
+
* credential string. Backslashes / double-quotes are escaped with
|
|
165
|
+
* defensive replacement.
|
|
166
|
+
*/
|
|
167
|
+
function composeFormBYaml(username, password) {
|
|
168
|
+
const escape = (v) => v.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
169
|
+
return `auth:\n credentials:\n username: "${escape(username)}"\n password: "${escape(password)}"\n`;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Run the `auth init` interactive flow:
|
|
173
|
+
*
|
|
174
|
+
* 1. TTY gate — refuse non-TTY stdin BEFORE any prompt (CI safety).
|
|
175
|
+
* 2. Resolve target path; refuse pre-existing files unless `--force`.
|
|
176
|
+
* 3. Form selector (A / B).
|
|
177
|
+
* 4. Form A: detect `op` CLI; on present → vault picker, item picker,
|
|
178
|
+
* confirm → compose YAML. On absent OR list-failure → freeform
|
|
179
|
+
* `op://` text prompt with regex validation.
|
|
180
|
+
* 5. Form B: explicit confirmation gate (default `N` aborts cleanly);
|
|
181
|
+
* on `Y` → username (email) + password (masked) → compose YAML.
|
|
182
|
+
* 6. Persist via `writeNewConfig` — atomic temp+rename, mode 0o600,
|
|
183
|
+
* sync-root + symlink refusal applies.
|
|
184
|
+
* 7. Confirmation message names path AND form.
|
|
185
|
+
*
|
|
186
|
+
* Cancellation: `@clack/prompts` returns its `isCancel` symbol on
|
|
187
|
+
* Ctrl-C / Esc at any prompt; we intercept and produce a `cancelled`
|
|
188
|
+
* result so the user sees an "Aborted" line and exits non-zero (vs. a
|
|
189
|
+
* silently truncated write).
|
|
190
|
+
*
|
|
191
|
+
* Inputs: `options` from commander; `opCli` is dependency-injected so
|
|
192
|
+
* tests can inject a stubbed implementation without spawning real
|
|
193
|
+
* `op` subprocesses.
|
|
194
|
+
*/
|
|
195
|
+
export async function runAuthInit(options, opCli = defaultOpCli) {
|
|
196
|
+
// 1. Non-TTY refusal — first thing, before we touch the prompt library.
|
|
197
|
+
if (!isStdinTty()) {
|
|
198
|
+
return {
|
|
199
|
+
status: "refused",
|
|
200
|
+
reason: "non-tty",
|
|
201
|
+
message: "ttctl auth init is interactive; pipe stdin or a TTY is required. " +
|
|
202
|
+
"Hand-author the config or run on a terminal.",
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const targetPath = resolveTargetPath(options);
|
|
206
|
+
const force = options.force === true;
|
|
207
|
+
// 2. Pre-existence gate — surfaced BEFORE any prompt so the user
|
|
208
|
+
// doesn't waste time entering credentials only to be refused at write
|
|
209
|
+
// time. `writeNewConfig` re-checks atomically (defense-in-depth
|
|
210
|
+
// against a TOCTOU window between this check and the open() call), so
|
|
211
|
+
// the refusal here is purely UX.
|
|
212
|
+
if (!force && existsSync(targetPath)) {
|
|
213
|
+
const message = `Refusing to overwrite existing config at ${targetPath}. ` + `Use --force to replace, or edit the file manually.`;
|
|
214
|
+
return { status: "refused", reason: "exists", message };
|
|
215
|
+
}
|
|
216
|
+
p.intro("ttctl auth init");
|
|
217
|
+
// 3. Form selector. clack returns either Value | Symbol(cancel); we
|
|
218
|
+
// narrow via isCancel before consuming.
|
|
219
|
+
const form = await p.select({
|
|
220
|
+
message: "Choose credentials source",
|
|
221
|
+
options: [
|
|
222
|
+
{ value: "A", label: "1Password reference (recommended)" },
|
|
223
|
+
{ value: "B", label: "Literal username/password (discouraged)" },
|
|
224
|
+
],
|
|
225
|
+
initialValue: "A",
|
|
226
|
+
});
|
|
227
|
+
if (p.isCancel(form)) {
|
|
228
|
+
p.cancel("Aborted (no file written).");
|
|
229
|
+
return { status: "refused", reason: "cancelled", message: "Aborted (no file written)." };
|
|
230
|
+
}
|
|
231
|
+
let yaml;
|
|
232
|
+
let chosenForm;
|
|
233
|
+
if (form === "A") {
|
|
234
|
+
chosenForm = "A";
|
|
235
|
+
const ref = await collectFormARef(opCli);
|
|
236
|
+
if (ref === undefined) {
|
|
237
|
+
p.cancel("Aborted (no file written).");
|
|
238
|
+
return { status: "refused", reason: "cancelled", message: "Aborted (no file written)." };
|
|
239
|
+
}
|
|
240
|
+
yaml = composeFormAYaml(ref);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
chosenForm = "B";
|
|
244
|
+
const literal = await collectFormBLiteral();
|
|
245
|
+
if (literal === undefined) {
|
|
246
|
+
p.cancel("Aborted (no file written).");
|
|
247
|
+
return { status: "refused", reason: "cancelled", message: "Aborted (no file written)." };
|
|
248
|
+
}
|
|
249
|
+
yaml = composeFormBYaml(literal.username, literal.password);
|
|
250
|
+
}
|
|
251
|
+
// 4. Persist via writeNewConfig — atomic temp+rename. The
|
|
252
|
+
// `assertSafePath` gate (sync-root, symlink) and the defense-in-depth
|
|
253
|
+
// existence re-check live inside writeNewConfig; surface any failure
|
|
254
|
+
// verbatim.
|
|
255
|
+
try {
|
|
256
|
+
await writeNewConfig(targetPath, yaml, { force });
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
260
|
+
p.cancel(`Failed to write config: ${message}`);
|
|
261
|
+
return { status: "error", message: `Failed to write config: ${message}` };
|
|
262
|
+
}
|
|
263
|
+
const successLine = formatInitOutput({ status: "written", path: targetPath, form: chosenForm });
|
|
264
|
+
p.outro(successLine);
|
|
265
|
+
return { status: "written", path: targetPath, form: chosenForm };
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Form A flow: collect a 1Password reference from either the vault/item
|
|
269
|
+
* picker (when `op` is installed and the listings parse cleanly) or a
|
|
270
|
+
* freeform text prompt.
|
|
271
|
+
*
|
|
272
|
+
* Returns `undefined` on cancellation at any sub-prompt.
|
|
273
|
+
*/
|
|
274
|
+
async function collectFormARef(opCli) {
|
|
275
|
+
const opAvailable = opCli.detect();
|
|
276
|
+
if (!opAvailable) {
|
|
277
|
+
p.log.info("1Password CLI (`op`) not installed; falling back to freeform reference.");
|
|
278
|
+
return promptFreeformOpRef();
|
|
279
|
+
}
|
|
280
|
+
// Vault list — fall back to freeform on any failure (op signed-out,
|
|
281
|
+
// JSON shape drift, network etc.). The user sees a clear stderr-style
|
|
282
|
+
// warning before the prompt to explain the fallback.
|
|
283
|
+
let vaults;
|
|
284
|
+
try {
|
|
285
|
+
vaults = opCli.listVaults();
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
289
|
+
p.log.warn(`op vault list failed (${reason}); falling back to freeform reference.`);
|
|
290
|
+
return promptFreeformOpRef();
|
|
291
|
+
}
|
|
292
|
+
if (vaults.length === 0) {
|
|
293
|
+
p.log.warn("op vault list returned no vaults; falling back to freeform reference.");
|
|
294
|
+
return promptFreeformOpRef();
|
|
295
|
+
}
|
|
296
|
+
const vault = await p.select({
|
|
297
|
+
message: "Pick a 1Password vault",
|
|
298
|
+
options: vaults.map((v) => ({ value: v.name, label: v.name })),
|
|
299
|
+
});
|
|
300
|
+
if (p.isCancel(vault))
|
|
301
|
+
return undefined;
|
|
302
|
+
let items;
|
|
303
|
+
try {
|
|
304
|
+
items = opCli.listItems(vault);
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
308
|
+
p.log.warn(`op item list failed (${reason}); falling back to freeform reference.`);
|
|
309
|
+
return promptFreeformOpRef();
|
|
310
|
+
}
|
|
311
|
+
if (items.length === 0) {
|
|
312
|
+
p.log.warn(`No LOGIN-category items in vault "${vault}"; falling back to freeform reference.`);
|
|
313
|
+
return promptFreeformOpRef();
|
|
314
|
+
}
|
|
315
|
+
const item = await p.select({
|
|
316
|
+
message: `Pick a LOGIN item from ${vault}`,
|
|
317
|
+
options: items.map((i) => ({ value: i.title, label: i.title })),
|
|
318
|
+
});
|
|
319
|
+
if (p.isCancel(item))
|
|
320
|
+
return undefined;
|
|
321
|
+
const ref = `op://${vault}/${item}`;
|
|
322
|
+
const confirmed = await p.confirm({
|
|
323
|
+
message: `Confirm: write ${ref} to config?`,
|
|
324
|
+
initialValue: true,
|
|
325
|
+
});
|
|
326
|
+
if (p.isCancel(confirmed) || !confirmed)
|
|
327
|
+
return undefined;
|
|
328
|
+
return ref;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Freeform `op://` reference fallback prompt. Validates input against the
|
|
332
|
+
* same regex as `OnePasswordReferenceSchema` in core; rejects until the
|
|
333
|
+
* user enters a valid value or cancels.
|
|
334
|
+
*/
|
|
335
|
+
async function promptFreeformOpRef() {
|
|
336
|
+
const ref = await p.text({
|
|
337
|
+
message: "1Password reference (op://[account/]vault/item)",
|
|
338
|
+
placeholder: "op://Personal/ttctl",
|
|
339
|
+
validate: (value) => {
|
|
340
|
+
if (value === undefined || value.length === 0)
|
|
341
|
+
return "Reference is required.";
|
|
342
|
+
if (!OP_REF_REGEX.test(value))
|
|
343
|
+
return OP_REF_PATTERN_HINT;
|
|
344
|
+
return undefined;
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
if (p.isCancel(ref))
|
|
348
|
+
return undefined;
|
|
349
|
+
return ref;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Form B flow: warn-and-confirm gate, then prompt for username (email
|
|
353
|
+
* regex) and password (masked). Returns `undefined` on any
|
|
354
|
+
* cancellation OR explicit `N` at the warn-and-confirm gate.
|
|
355
|
+
*/
|
|
356
|
+
async function collectFormBLiteral() {
|
|
357
|
+
const proceed = await p.confirm({
|
|
358
|
+
message: "Plaintext credentials in config are discouraged. Prefer Form A (1Password) when possible. Continue?",
|
|
359
|
+
initialValue: false,
|
|
360
|
+
});
|
|
361
|
+
if (p.isCancel(proceed) || !proceed)
|
|
362
|
+
return undefined;
|
|
363
|
+
const username = await p.text({
|
|
364
|
+
message: "Username (Toptal email)",
|
|
365
|
+
validate: (value) => {
|
|
366
|
+
if (value === undefined || value.length === 0)
|
|
367
|
+
return "Username is required.";
|
|
368
|
+
if (!EMAIL_REGEX.test(value))
|
|
369
|
+
return "Expected an email address.";
|
|
370
|
+
return undefined;
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
if (p.isCancel(username))
|
|
374
|
+
return undefined;
|
|
375
|
+
const password = await p.password({
|
|
376
|
+
message: "Password",
|
|
377
|
+
validate: (value) => {
|
|
378
|
+
if (value === undefined || value.length === 0)
|
|
379
|
+
return "Password is required.";
|
|
380
|
+
return undefined;
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
if (p.isCancel(password))
|
|
384
|
+
return undefined;
|
|
385
|
+
return { username, password };
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/auth/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ConfigErrorCode, SignInErrorCode } from "@ttctl/core";
|
|
2
|
+
import type { OutputFormat } from "../../lib/output.js";
|
|
3
|
+
/**
|
|
4
|
+
* Output format for `ttctl auth signin`. Aligned with the cross-CLI
|
|
5
|
+
* `OutputFormat` post-#126: `pretty` (default) is the human-readable
|
|
6
|
+
* confirmation line, `json` emits the `SignInResult` discriminated
|
|
7
|
+
* union for scripting, `yaml` emits the same shape as block-style YAML.
|
|
8
|
+
*/
|
|
9
|
+
export interface AuthSignInOptions {
|
|
10
|
+
output: OutputFormat;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* CLI-level error code surfaced in JSON output. Extends `SignInErrorCode`
|
|
14
|
+
* (from core) with codes specific to the orchestration this command performs
|
|
15
|
+
* around the core `signIn` call (1Password resolution, token persistence)
|
|
16
|
+
* plus the `ConfigErrorCode` discriminator from core's resolver. Stable
|
|
17
|
+
* strings — script consumers can branch on them without pattern-matching
|
|
18
|
+
* prose messages.
|
|
19
|
+
*/
|
|
20
|
+
export type SignInResultErrorCode = SignInErrorCode | ConfigErrorCode | "ONEPASSWORD_ERROR" | "SAVE_FAILED" | "NO_CREDENTIALS";
|
|
21
|
+
/**
|
|
22
|
+
* Terminal outcome of `ttctl auth signin`. `signed-in` carries the verified
|
|
23
|
+
* `email` (the same string passed to `EmailPasswordSignIn`). `error` carries
|
|
24
|
+
* a stable `code` for scripting plus a human-readable `message` already
|
|
25
|
+
* containing any actionable hint.
|
|
26
|
+
*/
|
|
27
|
+
export type SignInResult = {
|
|
28
|
+
status: "signed-in";
|
|
29
|
+
email: string;
|
|
30
|
+
} | {
|
|
31
|
+
status: "error";
|
|
32
|
+
code: SignInResultErrorCode;
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Map a `SignInResult` to a process exit code:
|
|
37
|
+
* - `signed-in` → 0 (success)
|
|
38
|
+
* - `error`/`NETWORK_ERROR` → 2 (transient/retryable — same convention as
|
|
39
|
+
* `auth status` `unreachable`)
|
|
40
|
+
* - `error`/anything else → 1 (user-actionable: bad credentials, missing
|
|
41
|
+
* 1Password CLI, malformed config, MFA required, disk failure)
|
|
42
|
+
*
|
|
43
|
+
* The 1/2 split matches `auth status` so shell consumers can compose:
|
|
44
|
+
* `ttctl auth signin || case $? in 1) ... ;; 2) retry ;; esac`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function exitCodeForSignInResult(result: SignInResult): number;
|
|
47
|
+
/**
|
|
48
|
+
* Render a `SignInResult` for the human-readable `pretty` format.
|
|
49
|
+
* Success collapses to a single-line confirmation; failures surface the
|
|
50
|
+
* underlying message verbatim (the upstream errors already carry
|
|
51
|
+
* actionable hints — `OnePasswordError` names the install URL,
|
|
52
|
+
* `ConfigError` names the missing path).
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatSignInPretty(result: SignInResult): string;
|
|
55
|
+
/**
|
|
56
|
+
* Format a `SignInResult` for the requested output mode. The JSON and
|
|
57
|
+
* YAML shapes mirror the discriminated union 1:1 — `email` only on
|
|
58
|
+
* success, `code` and `message` only on error — so callers can consume
|
|
59
|
+
* the same union structure over the wire.
|
|
60
|
+
*/
|
|
61
|
+
export declare function formatSignInOutput(result: SignInResult, output: OutputFormat): string;
|
|
62
|
+
/**
|
|
63
|
+
* Run the `auth signin` command end-to-end:
|
|
64
|
+
* 1. Discover and load `.ttctl.yaml` (`ConfigError` on missing/invalid).
|
|
65
|
+
* 2. Refuse Form C (token-only, no credentials) per FR-3.3 — signin
|
|
66
|
+
* requires `auth.credentials` to be configured.
|
|
67
|
+
* 3. Resolve credentials — Form A reaches `op` CLI, Form B is literal
|
|
68
|
+
* (`OnePasswordError` on Form A failures).
|
|
69
|
+
* 4. Sign in via `core.signIn`, capturing the bearer token.
|
|
70
|
+
* 5. Persist the token back to the SAME YAML config under `auth.token`
|
|
71
|
+
* via `persistAuthToken` — atomic write, mode 0600, comment fidelity,
|
|
72
|
+
* symlink + sync-root refusal.
|
|
73
|
+
* 6. Emit the result and exit with the corresponding code.
|
|
74
|
+
*
|
|
75
|
+
* Errors are routed to stderr; success goes to stdout. `process.exit` is the
|
|
76
|
+
* terminal step for the same reason as `auth status` — Commander action
|
|
77
|
+
* handlers otherwise resolve to `undefined` and we'd lose the exit-code
|
|
78
|
+
* contract that scripts rely on.
|
|
79
|
+
*/
|
|
80
|
+
export declare function runAuthSignIn(options: AuthSignInOptions): Promise<void>;
|
|
81
|
+
//# sourceMappingURL=signin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signin.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/signin.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAIpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,aAAa,GACb,gBAAgB,CAAC;AAErB;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAIpE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAK/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAQrF;AA6BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7E"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { AuthTokenPersistError, ConfigError, OnePasswordError, SignInError, persistAuthToken, resolveCredentials, signIn, } from "@ttctl/core";
|
|
4
|
+
import { resolveConfigForCli } from "../../lib/config-context.js";
|
|
5
|
+
import { formatYaml } from "../../lib/output.js";
|
|
6
|
+
/**
|
|
7
|
+
* Map a `SignInResult` to a process exit code:
|
|
8
|
+
* - `signed-in` → 0 (success)
|
|
9
|
+
* - `error`/`NETWORK_ERROR` → 2 (transient/retryable — same convention as
|
|
10
|
+
* `auth status` `unreachable`)
|
|
11
|
+
* - `error`/anything else → 1 (user-actionable: bad credentials, missing
|
|
12
|
+
* 1Password CLI, malformed config, MFA required, disk failure)
|
|
13
|
+
*
|
|
14
|
+
* The 1/2 split matches `auth status` so shell consumers can compose:
|
|
15
|
+
* `ttctl auth signin || case $? in 1) ... ;; 2) retry ;; esac`.
|
|
16
|
+
*/
|
|
17
|
+
export function exitCodeForSignInResult(result) {
|
|
18
|
+
if (result.status === "signed-in")
|
|
19
|
+
return 0;
|
|
20
|
+
if (result.code === "NETWORK_ERROR")
|
|
21
|
+
return 2;
|
|
22
|
+
return 1;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Render a `SignInResult` for the human-readable `pretty` format.
|
|
26
|
+
* Success collapses to a single-line confirmation; failures surface the
|
|
27
|
+
* underlying message verbatim (the upstream errors already carry
|
|
28
|
+
* actionable hints — `OnePasswordError` names the install URL,
|
|
29
|
+
* `ConfigError` names the missing path).
|
|
30
|
+
*/
|
|
31
|
+
export function formatSignInPretty(result) {
|
|
32
|
+
if (result.status === "signed-in") {
|
|
33
|
+
return `Signed in as ${result.email}`;
|
|
34
|
+
}
|
|
35
|
+
return `Sign-in failed (${result.code}): ${result.message}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format a `SignInResult` for the requested output mode. The JSON and
|
|
39
|
+
* YAML shapes mirror the discriminated union 1:1 — `email` only on
|
|
40
|
+
* success, `code` and `message` only on error — so callers can consume
|
|
41
|
+
* the same union structure over the wire.
|
|
42
|
+
*/
|
|
43
|
+
export function formatSignInOutput(result, output) {
|
|
44
|
+
if (output === "json") {
|
|
45
|
+
return JSON.stringify(result);
|
|
46
|
+
}
|
|
47
|
+
if (output === "yaml") {
|
|
48
|
+
return formatYaml(result);
|
|
49
|
+
}
|
|
50
|
+
return formatSignInPretty(result);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Translate a thrown error to a `SignInResult` with the stable error code.
|
|
54
|
+
* Centralizes the error-class → code mapping so the run loop stays linear.
|
|
55
|
+
*/
|
|
56
|
+
function classifyError(err) {
|
|
57
|
+
if (err instanceof SignInError) {
|
|
58
|
+
return { status: "error", code: err.code, message: err.message };
|
|
59
|
+
}
|
|
60
|
+
if (err instanceof OnePasswordError) {
|
|
61
|
+
return { status: "error", code: "ONEPASSWORD_ERROR", message: err.message };
|
|
62
|
+
}
|
|
63
|
+
if (err instanceof ConfigError) {
|
|
64
|
+
return { status: "error", code: err.code, message: err.message };
|
|
65
|
+
}
|
|
66
|
+
if (err instanceof AuthTokenPersistError) {
|
|
67
|
+
// Surface bearer in the rescue line per AC-4 — operator can save manually.
|
|
68
|
+
const rescue = err.bearerRescue !== undefined ? `\nBearer (rescue): ${err.bearerRescue}` : "";
|
|
69
|
+
return {
|
|
70
|
+
status: "error",
|
|
71
|
+
code: "SAVE_FAILED",
|
|
72
|
+
message: `${err.message}${rescue}`,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
76
|
+
return { status: "error", code: "UNKNOWN", message };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Run the `auth signin` command end-to-end:
|
|
80
|
+
* 1. Discover and load `.ttctl.yaml` (`ConfigError` on missing/invalid).
|
|
81
|
+
* 2. Refuse Form C (token-only, no credentials) per FR-3.3 — signin
|
|
82
|
+
* requires `auth.credentials` to be configured.
|
|
83
|
+
* 3. Resolve credentials — Form A reaches `op` CLI, Form B is literal
|
|
84
|
+
* (`OnePasswordError` on Form A failures).
|
|
85
|
+
* 4. Sign in via `core.signIn`, capturing the bearer token.
|
|
86
|
+
* 5. Persist the token back to the SAME YAML config under `auth.token`
|
|
87
|
+
* via `persistAuthToken` — atomic write, mode 0600, comment fidelity,
|
|
88
|
+
* symlink + sync-root refusal.
|
|
89
|
+
* 6. Emit the result and exit with the corresponding code.
|
|
90
|
+
*
|
|
91
|
+
* Errors are routed to stderr; success goes to stdout. `process.exit` is the
|
|
92
|
+
* terminal step for the same reason as `auth status` — Commander action
|
|
93
|
+
* handlers otherwise resolve to `undefined` and we'd lose the exit-code
|
|
94
|
+
* contract that scripts rely on.
|
|
95
|
+
*/
|
|
96
|
+
export async function runAuthSignIn(options) {
|
|
97
|
+
const result = await performSignIn();
|
|
98
|
+
const rendered = formatSignInOutput(result, options.output);
|
|
99
|
+
const stream = result.status === "signed-in" ? process.stdout : process.stderr;
|
|
100
|
+
stream.write(rendered + "\n");
|
|
101
|
+
process.exit(exitCodeForSignInResult(result));
|
|
102
|
+
}
|
|
103
|
+
async function performSignIn() {
|
|
104
|
+
let configResult;
|
|
105
|
+
try {
|
|
106
|
+
configResult = resolveConfigForCli();
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return classifyError(err);
|
|
110
|
+
}
|
|
111
|
+
// Form C refusal (FR-3.3): signin requires credentials. A token-only
|
|
112
|
+
// config has no credentials to drive EmailPasswordSignIn.
|
|
113
|
+
const credentialsValue = configResult.config.auth.credentials;
|
|
114
|
+
if (credentialsValue === undefined) {
|
|
115
|
+
return {
|
|
116
|
+
status: "error",
|
|
117
|
+
code: "NO_CREDENTIALS",
|
|
118
|
+
message: "ttctl auth signin requires `auth.credentials` to be configured. " +
|
|
119
|
+
'Add a 1Password reference (`auth.credentials: "op://..."`) or literal ' +
|
|
120
|
+
"`{ username, password }` to your config and try again.",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
let credentials;
|
|
124
|
+
try {
|
|
125
|
+
credentials = resolveCredentials(credentialsValue);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
return classifyError(err);
|
|
129
|
+
}
|
|
130
|
+
let token;
|
|
131
|
+
try {
|
|
132
|
+
({ token } = await signIn(credentials));
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
return classifyError(err);
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
await persistAuthToken(configResult.path, token);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
return classifyError(err);
|
|
142
|
+
}
|
|
143
|
+
return { status: "signed-in", email: credentials.email };
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=signin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signin.js","sourceRoot":"","sources":["../../../src/commands/auth/signin.ts"],"names":[],"mappings":"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"}
|