create-agit 0.2.0 → 0.2.2

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.
Files changed (2) hide show
  1. package/bin.mjs +39 -10
  2. package/package.json +2 -2
package/bin.mjs CHANGED
@@ -13,6 +13,8 @@
13
13
  */
14
14
 
15
15
  import { createRequire } from 'node:module'
16
+ import { randomUUID } from 'node:crypto'
17
+ import { performance } from 'node:perf_hooks'
16
18
  import { chmodSync, copyFileSync, mkdirSync } from 'node:fs'
17
19
  import { homedir, platform, arch } from 'node:os'
18
20
  import { join, delimiter } from 'node:path'
@@ -65,17 +67,43 @@ function main() {
65
67
 
66
68
  say('agent-git installer')
67
69
 
70
+ const yes = ['1', 'true'].includes(process.env.npm_config_yes?.toLowerCase()) || args.some(a => a === '--yes' || a === '-y')
71
+ const installerEnv = { ...process.env, AGIT_INSTALL_CHANNEL: 'create_agit', AGIT_INSTALLER_YES: yes ? '1' : '0',
72
+ ...(acquisitionId ? { AGIT_ACQUISITION_ID: acquisitionId } : {}),
73
+ ...(campaignUrl ? { AGIT_CAMPAIGN_URL: campaignUrl } : {}) }
74
+ const attemptId = randomUUID()
75
+ const started = performance.now()
76
+ const report = (stage, outcome, since = started, errorCategory = 'none') => {
77
+ spawnSync(bin, ['--internal-install-stage', JSON.stringify({
78
+ attempt_id: attemptId, stage, outcome, elapsed_ms: Math.round(performance.now() - since), error_category: errorCategory,
79
+ })], { stdio: 'inherit', env: installerEnv, ...(stage === 'started' ? {} : { timeout: 2000 }) })
80
+ }
81
+ report('started', 'started')
82
+ installerEnv.AGIT_INSTALLER_ONBOARDING_HANDLED = '1'
68
83
  const targetDir = join(homedir(), '.local', 'bin')
69
- mkdirSync(targetDir, { recursive: true })
70
84
  const target = join(targetDir, binaryName())
71
- copyFileSync(bin, target)
72
- chmodSync(target, 0o755)
85
+ const copying = performance.now()
86
+ try {
87
+ mkdirSync(targetDir, { recursive: true })
88
+ copyFileSync(bin, target)
89
+ chmodSync(target, 0o755)
90
+ report('binary_copy', 'ok', copying)
91
+ } catch (error) {
92
+ report('binary_copy', 'error', copying, 'filesystem')
93
+ report('finished', 'error', started, 'filesystem')
94
+ fail(`could not install the binary: ${error.message}`)
95
+ process.exit(1)
96
+ }
73
97
 
98
+ const verifying = performance.now()
74
99
  const check = spawnSync(target, ['--version'], { encoding: 'utf8', env: { ...process.env, AGIT_TELEMETRY_DEFER: '1' } })
75
100
  if (check.error || check.status !== 0) {
101
+ report('verification', 'error', verifying, 'binary')
102
+ report('finished', 'error', started, 'binary')
76
103
  fail(`the binary did not run: ${(check.stderr || check.error?.message || `exit ${check.status}`).trim()}`)
77
104
  process.exit(1)
78
105
  }
106
+ report('verification', 'ok', verifying)
79
107
  ok(`installed ${check.stdout.trim()} → ${target}`)
80
108
 
81
109
  if (!process.env.PATH?.split(delimiter).includes(targetDir)) {
@@ -85,22 +113,23 @@ function main() {
85
113
  // "installed by default at download time": hooks + skill + MCP + AGENTS.md in one pass. A
86
114
  // failure does not block the install itself — the binary is already there, and setup can be
87
115
  // re-run by hand later.
88
- const yes = ['1', 'true'].includes(process.env.npm_config_yes?.toLowerCase()) || process.argv.slice(2).some(a => a === '--yes' || a === '-y')
89
- spawnSync(target, ['--internal-install-completed'], {
90
- stdio: ['ignore', 'inherit', 'inherit'],
91
- env: { ...process.env, AGIT_INSTALL_CHANNEL: 'create_agit', AGIT_INSTALLER_YES: yes ? '1' : '0',
92
- ...(acquisitionId ? { AGIT_ACQUISITION_ID: acquisitionId } : {}),
93
- ...(campaignUrl ? { AGIT_CAMPAIGN_URL: campaignUrl } : {}) },
116
+ spawnSync(target, ['--internal-install-completed', '--defer-notice'], {
117
+ stdio: ['ignore', 'inherit', 'inherit'], env: installerEnv,
94
118
  })
95
119
  const skipSetup = process.env.AGIT_SKIP_SETUP && !['0', 'false'].includes(process.env.AGIT_SKIP_SETUP.toLowerCase())
96
120
  if (skipSetup) {
121
+ report('setup', 'skipped', performance.now())
122
+ report('finished', 'ok')
97
123
  dim('Setup skipped by AGIT_SKIP_SETUP. Run `agit setup` when ready.')
98
124
  return
99
125
  }
126
+ const integrating = performance.now()
100
127
  const setup = spawnSync(target, yes ? ['setup', '--yes'] : ['setup'], {
101
128
  stdio: 'inherit',
102
- env: { ...process.env, AGIT_INSTALL_CHANNEL: 'create_agit', AGIT_INSTALLER_YES: yes ? '1' : '0' },
129
+ env: installerEnv,
103
130
  })
131
+ report('setup', setup.status === 0 ? 'ok' : 'error', integrating, setup.status === 0 ? 'none' : 'integration')
132
+ report('finished', setup.status === 0 ? 'ok' : 'partial', started, setup.status === 0 ? 'none' : 'integration')
104
133
  if (setup.status === 0) {
105
134
  ok('integrations installed (skills · hooks · MCP · AGENTS.md)')
106
135
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agit",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "One-line installer for agit (npx create-agit) — thin wrapper around @einsia/agent-git that lands the CLI at ~/.local/bin and wires skills/hooks/MCP.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,7 +8,7 @@
8
8
  "create-agit": "./bin.mjs"
9
9
  },
10
10
  "dependencies": {
11
- "@einsia/agent-git": "0.2.0"
11
+ "@einsia/agent-git": "0.2.2"
12
12
  },
13
13
  "engines": {
14
14
  "node": ">=20"