devvami 1.1.1 → 1.2.0

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/src/types.js CHANGED
@@ -260,3 +260,69 @@
260
260
  * @property {string} owner - GitHub owner (org or user)
261
261
  * @property {string} repo - Repository name
262
262
  */
263
+
264
+ /**
265
+ * @typedef {Object} SecurityTool
266
+ * @property {string} id - Unique identifier (e.g., "aws-vault", "pass", "gpg", "gcm", "osxkeychain")
267
+ * @property {string} displayName - Human-readable name for UI output
268
+ * @property {'aws'|'git'|'dependency'} role - What the tool protects; 'dependency' = required by another tool
269
+ * @property {'not-installed'|'installed'|'misconfigured'|'skipped'|'n/a'} status - Status after check phase
270
+ * @property {Platform[]} platforms - Platforms where this tool applies
271
+ * @property {string|null} version - Detected version string, if available
272
+ * @property {string|null} hint - Actionable message when status is 'misconfigured' or 'not-installed'
273
+ */
274
+
275
+ /**
276
+ * @typedef {Object} SetupStep
277
+ * @property {string} id - Unique step identifier (e.g., "install-aws-vault", "init-pass")
278
+ * @property {string} label - Human-readable description shown to the developer
279
+ * @property {string} toolId - The SecurityTool this step belongs to
280
+ * @property {'check'|'install'|'configure'|'verify'} type - Step category
281
+ * @property {() => Promise<StepResult>} run - Async function that executes the step
282
+ * @property {boolean} requiresConfirmation - True for 'install' and 'configure' steps
283
+ * @property {boolean} [skippable] - True if the developer can skip this step without breaking subsequent steps
284
+ * @property {boolean} [gpgInteractive] - True if the step spawns GPG interactively (requires stdio:inherit)
285
+ */
286
+
287
+ /**
288
+ * @typedef {Object} StepResult
289
+ * @property {'success'|'skipped'|'failed'} status
290
+ * @property {string} [message] - Human-readable outcome message
291
+ * @property {string} [hint] - Actionable recovery suggestion shown only when status is 'failed'
292
+ * @property {string} [hintUrl] - Documentation URL to include with the hint
293
+ */
294
+
295
+ /**
296
+ * @typedef {Object} SetupSession
297
+ * @property {Platform} platform - Detected platform for this run
298
+ * @property {'aws'|'git'|'both'} selection - What the developer chose to set up
299
+ * @property {SetupStep[]} steps - Ordered list of steps for this session
300
+ * @property {Map<string, StepResult>} results - Map of stepId → StepResult
301
+ * @property {'in-progress'|'completed'|'failed'|'cancelled'} overallStatus - Aggregate status
302
+ */
303
+
304
+ /**
305
+ * @typedef {Object} GpgKey
306
+ * @property {string} id - Long key ID (16-character hex)
307
+ * @property {string} fingerprint - Full 40-character fingerprint
308
+ * @property {string} name - Associated name from the key's UID
309
+ * @property {string} email - Associated email from the key's UID
310
+ * @property {string|null} expiry - Expiry date as ISO8601 string, or null if no expiry
311
+ */
312
+
313
+ /**
314
+ * @typedef {Object} SecurityToolStatus
315
+ * @property {string} id - Tool id
316
+ * @property {string} displayName - Human-readable name
317
+ * @property {'not-installed'|'installed'|'misconfigured'|'n/a'} status - Current status
318
+ * @property {string|null} version - Detected version, if any
319
+ * @property {string|null} hint - Recovery hint if misconfigured
320
+ */
321
+
322
+ /**
323
+ * @typedef {Object} SecuritySetupJsonResult
324
+ * @property {Platform} platform - Detected platform
325
+ * @property {'aws'|'git'|'both'|null} selection - Selection made (null for --json health check)
326
+ * @property {SecurityToolStatus[]} tools - Status of each applicable tool
327
+ * @property {'success'|'partial'|'not-configured'} overallStatus - Aggregate status
328
+ */
@@ -0,0 +1,173 @@
1
+ import chalk from 'chalk'
2
+ import { printBanner } from './banner.js'
3
+ import { isColorEnabled } from './gradient.js'
4
+ import { typewriterLine } from './typewriter.js'
5
+
6
+ // ─── Constants ────────────────────────────────────────────────────────────────
7
+
8
+ const STAGGER = 150
9
+ const delay = (ms) => new Promise((r) => setTimeout(r, ms))
10
+ const out = (line) => process.stdout.write(line + '\n')
11
+ const nl = () => process.stdout.write('\n')
12
+
13
+ // ─── Color palette ────────────────────────────────────────────────────────────
14
+
15
+ const p = isColorEnabled
16
+ ? {
17
+ sep: (t) => chalk.hex('#4A9EFF').dim(t),
18
+ cyan: (t) => chalk.hex('#00D4FF').bold(t),
19
+ green: (t) => chalk.hex('#00FF88').bold(t),
20
+ pink: (t) => chalk.hex('#FF3399').bold(t),
21
+ gold: (t) => chalk.hex('#FFD700').bold(t),
22
+ orange: (t) => chalk.hex('#FF6B2B').bold(t),
23
+ blue: (t) => chalk.hex('#4A9EFF')(t),
24
+ white: (t) => chalk.white(t),
25
+ dim: (t) => chalk.dim(t),
26
+ }
27
+ : Object.fromEntries(
28
+ ['sep', 'cyan', 'green', 'pink', 'gold', 'orange', 'blue', 'white', 'dim'].map((k) => [
29
+ k,
30
+ (t) => t,
31
+ ]),
32
+ )
33
+
34
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
35
+
36
+ /**
37
+ * Build a ruler-style section header.
38
+ * Example: " 🔐 SUPPLY CHAIN SECURITY ──────────────────────────────"
39
+ * No right-side border: dashes trail right, no alignment required.
40
+ *
41
+ * @param {string} icon
42
+ * @param {string} label
43
+ * @param {(t: string) => string} colorFn
44
+ * @returns {string}
45
+ */
46
+ function ruler(icon, label, colorFn) {
47
+ return colorFn(` ${icon} ${label} `) + p.sep('─'.repeat(40))
48
+ }
49
+
50
+ // ─── Welcome screen ───────────────────────────────────────────────────────────
51
+
52
+ /**
53
+ * Print the full cyberpunk dvmi welcome screen.
54
+ * Shows the animated DVMI logo followed by a styled mission dashboard.
55
+ * Falls back to plain text in non-TTY / NO_COLOR / CI environments.
56
+ *
57
+ * @param {string} [version=''] - CLI version string (e.g. '2.1.0')
58
+ * @returns {Promise<void>}
59
+ */
60
+ export async function printWelcomeScreen(version = '') {
61
+ // ── 1. Animated DVMI logo ──────────────────────────────────────────────────
62
+ await printBanner()
63
+
64
+ // ── 2. Badge line (typewriter with brand gradient) ─────────────────────────
65
+ const versionTag = version ? `v${version} · ` : ''
66
+ await typewriterLine(` ◆ Developer Mission Interface · ${versionTag}Node >= 24`)
67
+
68
+ // ── 3. Connection established ──────────────────────────────────────────────
69
+ await delay(STAGGER)
70
+ nl()
71
+ out(p.sep(' ' + '─'.repeat(72)))
72
+ nl()
73
+ out(p.cyan(' LINK ESTABLISHED'))
74
+ nl()
75
+ out(p.white(' dvmi consolidates the operational surface of modern software delivery into'))
76
+ out(p.white(' one deterministic CLI experience. Instead of context switching across browser'))
77
+ out(p.white(' tabs, dashboards, and disconnected tools, you run critical workflows from a'))
78
+ out(p.white(' single terminal interface: consistent output, predictable behavior, full control.'))
79
+
80
+ // ── 4. Mission profile ─────────────────────────────────────────────────────
81
+ await delay(STAGGER)
82
+ nl()
83
+ out(ruler('⚙️ ', 'MISSION PROFILE :: WHAT THIS CLI DOES', p.cyan))
84
+ nl()
85
+ const mission = [
86
+ 'discover and manage repositories across your GitHub organization',
87
+ 'handle pull requests with faster review and decision flow',
88
+ 'monitor CI/CD pipelines, inspect failures, rerun with intent',
89
+ 'query and read technical documentation without leaving the shell',
90
+ 'track execution priorities through task-oriented commands',
91
+ 'inspect cloud costs early, before budget drift becomes an incident',
92
+ ]
93
+ for (const line of mission) {
94
+ out(p.dim(' - ') + p.white(line))
95
+ }
96
+
97
+ // ── 5. Supply chain security ───────────────────────────────────────────────
98
+ await delay(STAGGER)
99
+ nl()
100
+ out(ruler('🔐', "SUPPLY CHAIN SECURITY :: VERIFY, DON'T GUESS", p.green))
101
+ nl()
102
+ out(p.dim(' dvmi takes a security-first but pragmatic approach to software delivery:'))
103
+ nl()
104
+ const security = [
105
+ 'artifact integrity and provenance-aware delivery workflow',
106
+ 'dependency visibility with an SBOM mindset (SPDX / CycloneDX)',
107
+ 'continuous hygiene on dependency risk and secret exposure',
108
+ 'credential management via OS-native secure storage (keychain)',
109
+ 'less improvised shell procedures, more repeatable safe operations',
110
+ ]
111
+ for (const line of security) {
112
+ out(p.green(' ▸ ') + p.white(line))
113
+ }
114
+ nl()
115
+ out(p.dim(' Objective: reduce the risk surface without slowing down delivery.'))
116
+
117
+ // ── 6. DevEx high-velocity ─────────────────────────────────────────────────
118
+ await delay(STAGGER)
119
+ nl()
120
+ out(ruler('⚡', 'DEVEX HIGH-VELOCITY :: STAY IN FLOW', p.pink))
121
+ nl()
122
+ out(p.dim(' dvmi is designed to lower cognitive cost and keep you in flow:'))
123
+ nl()
124
+ const devex = [
125
+ 'less context switching between tools and dashboards',
126
+ 'less time spent hunting down "where did this break"',
127
+ 'faster "what is blocked / what is next" decision loops',
128
+ 'scriptable, composable output for automation and team workflows',
129
+ ]
130
+ for (const line of devex) {
131
+ out(p.pink(' ▸ ') + p.white(line))
132
+ }
133
+ nl()
134
+ out(p.dim(' No noise added. Operational signal only.'))
135
+
136
+ // ── 7. Delivery reliability ────────────────────────────────────────────────
137
+ await delay(STAGGER)
138
+ nl()
139
+ out(ruler('📡', 'DELIVERY RELIABILITY :: SHIP WITH CONTROL', p.orange))
140
+ nl()
141
+ out(p.white(' From PR readiness to pipeline health to release confidence,'))
142
+ out(p.white(' dvmi moves teams from reactive debugging to proactive control.'))
143
+ nl()
144
+ out(p.white(' Reliability is treated as a habit, not a phase.'))
145
+
146
+ // ── 8. Boot sequence ───────────────────────────────────────────────────────
147
+ await delay(STAGGER)
148
+ nl()
149
+ out(ruler('🚀', 'BOOT SEQUENCE', p.gold))
150
+ nl()
151
+
152
+ /** @type {Array<[string, string]>} */
153
+ const commands = [
154
+ ['dvmi init', 'configure your workspace'],
155
+ ['dvmi auth login', 'connect GitHub & ClickUp'],
156
+ ['dvmi pr status', 'open pull requests'],
157
+ ['dvmi pipeline status', 'CI/CD health check'],
158
+ ['dvmi tasks today', 'focus mode: what to ship today'],
159
+ ['dvmi costs get', 'AWS bill reality check'],
160
+ ['dvmi doctor', 'diagnose config issues'],
161
+ ]
162
+ for (const [cmd, comment] of commands) {
163
+ out(' ' + p.blue('$ ' + cmd.padEnd(24)) + p.dim('# ' + comment))
164
+ }
165
+
166
+ // ── 9. Closing ─────────────────────────────────────────────────────────────
167
+ await delay(STAGGER)
168
+ nl()
169
+ out(p.sep(' ' + '─'.repeat(72)))
170
+ nl()
171
+ out(p.dim(' DVMI PROTOCOL: ') + p.cyan('Ship fast. Verify everything.'))
172
+ nl()
173
+ }