@antomanc/aginit 0.1.0 → 0.3.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/LICENSE +1 -1
  3. package/README.md +96 -194
  4. package/THIRD_PARTY_NOTICES.md +11 -0
  5. package/dist/adapters/agent-browser.d.ts +54 -0
  6. package/dist/adapters/agent-browser.d.ts.map +1 -0
  7. package/dist/adapters/agent-browser.js +122 -0
  8. package/dist/adapters/agent-browser.js.map +1 -0
  9. package/dist/adapters/agents-md.d.ts.map +1 -1
  10. package/dist/adapters/agents-md.js +53 -23
  11. package/dist/adapters/agents-md.js.map +1 -1
  12. package/dist/adapters/browser.js.map +1 -1
  13. package/dist/adapters/git.d.ts.map +1 -1
  14. package/dist/adapters/git.js +2 -0
  15. package/dist/adapters/git.js.map +1 -1
  16. package/dist/adapters/graft.js.map +1 -1
  17. package/dist/adapters/package-manager.js.map +1 -1
  18. package/dist/adapters/skills.d.ts.map +1 -1
  19. package/dist/adapters/skills.js +11 -7
  20. package/dist/adapters/skills.js.map +1 -1
  21. package/dist/cli/doctor.d.ts.map +1 -1
  22. package/dist/cli/doctor.js +73 -7
  23. package/dist/cli/doctor.js.map +1 -1
  24. package/dist/cli/init.js.map +1 -1
  25. package/dist/cli/main.d.ts.map +1 -1
  26. package/dist/cli/main.js +17 -16
  27. package/dist/cli/main.js.map +1 -1
  28. package/dist/cli/new.d.ts +0 -1
  29. package/dist/cli/new.d.ts.map +1 -1
  30. package/dist/cli/new.js +22 -20
  31. package/dist/cli/new.js.map +1 -1
  32. package/dist/cli/wizard.d.ts +0 -4
  33. package/dist/cli/wizard.d.ts.map +1 -1
  34. package/dist/cli/wizard.js +4 -50
  35. package/dist/cli/wizard.js.map +1 -1
  36. package/dist/config/defaults.d.ts +16 -1
  37. package/dist/config/defaults.d.ts.map +1 -1
  38. package/dist/config/defaults.js +91 -10
  39. package/dist/config/defaults.js.map +1 -1
  40. package/dist/config/schema.d.ts +5 -0
  41. package/dist/config/schema.d.ts.map +1 -1
  42. package/dist/config/schema.js.map +1 -1
  43. package/dist/config/validation.d.ts +3 -3
  44. package/dist/config/validation.d.ts.map +1 -1
  45. package/dist/index.d.ts +1 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +1 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/presets/adr.js.map +1 -1
  50. package/dist/utils/fs.js.map +1 -1
  51. package/dist/utils/logger.d.ts.map +1 -1
  52. package/dist/utils/shell.js.map +1 -1
  53. package/package.json +22 -14
  54. package/src/adapters/agent-browser.ts +162 -0
  55. package/src/adapters/agents-md.ts +60 -26
  56. package/src/adapters/git.ts +2 -0
  57. package/src/adapters/skills.ts +10 -7
  58. package/src/cli/doctor.ts +81 -6
  59. package/src/cli/main.ts +17 -25
  60. package/src/cli/new.ts +25 -24
  61. package/src/cli/wizard.ts +4 -56
  62. package/src/config/defaults.ts +109 -12
  63. package/src/config/schema.ts +5 -0
  64. package/src/index.ts +1 -0
package/src/cli/new.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import pc from 'picocolors';
3
- import { getDefaultConfig } from '../config/defaults.js';
3
+ import { getDefaultConfig, upgradeLegacySkillConfig } from '../config/defaults.js';
4
4
  import {
5
5
  AGINIT_CONFIG_FILENAME,
6
6
  PresetType,
@@ -12,6 +12,11 @@ import { setupGit } from '../adapters/git.js';
12
12
  import { setupAgentsMarkdown } from '../adapters/agents-md.js';
13
13
  import { installAllSkills } from '../adapters/skills.js';
14
14
  import { initGraft } from '../adapters/graft.js';
15
+ import {
16
+ agentBrowserConfigured,
17
+ agentBrowserStubInstalled,
18
+ setupAgentBrowser
19
+ } from '../adapters/agent-browser.js';
15
20
  import { ensureDir, writeJsonFile } from '../utils/fs.js';
16
21
  import {
17
22
  readProjectConfig,
@@ -28,7 +33,6 @@ export interface NewProjectOptions {
28
33
  preset?: PresetType;
29
34
  framework?: WebFramework;
30
35
  packageManager?: PackageManager;
31
- specWorkflow?: boolean;
32
36
  skills?: boolean;
33
37
  graft?: boolean;
34
38
  git?: boolean;
@@ -73,8 +77,7 @@ export async function createProject(
73
77
  const presetHandler = getPreset(presetName);
74
78
  const defaults = getDefaultConfig(projectName, presetName, {
75
79
  framework,
76
- packageManager,
77
- specWorkflow: options.specWorkflow
80
+ packageManager
78
81
  });
79
82
  const config = validateConfig(
80
83
  existingConfig
@@ -88,22 +91,7 @@ export async function createProject(
88
91
  options.framework !== undefined || options.preset !== undefined
89
92
  ? { ...existingConfig.browser, ...defaults.browser }
90
93
  : existingConfig.browser,
91
- skills:
92
- options.specWorkflow !== undefined
93
- ? {
94
- ...existingConfig.skills,
95
- workflow: defaults.skills.workflow,
96
- sources: existingConfig.skills.sources.map((source) =>
97
- source.package === 'mattpocock/skills'
98
- ? {
99
- ...source,
100
- skills: defaults.skills.sources.find((s) => s.package === source.package)!
101
- .skills
102
- }
103
- : source
104
- )
105
- }
106
- : existingConfig.skills
94
+ skills: upgradeLegacySkillConfig(existingConfig.skills)
107
95
  }
108
96
  : defaults
109
97
  );
@@ -117,7 +105,11 @@ export async function createProject(
117
105
  );
118
106
  let complete = true;
119
107
 
120
- const totalSteps = 6;
108
+ // The agent-browser skill stub is inert without its CLI and browser
109
+ // binaries, so provisioning them gets its own step when the skill applies.
110
+ const agentBrowserWanted =
111
+ agentBrowserConfigured(config.skills.sources) || agentBrowserStubInstalled(targetDir);
112
+ const totalSteps = agentBrowserWanted ? 7 : 6;
121
113
  let currentStep = 1;
122
114
 
123
115
  // Scaffold into the clean directory before Git adds files that upstream tools reject.
@@ -168,7 +160,15 @@ export async function createProject(
168
160
  logger.dim('Skills installation skipped (--no-skills or empty configuration)');
169
161
  }
170
162
 
171
- // Step 6: Codebase intelligence (Graft)
163
+ // Provision the agent-browser runtime the skill stub drives
164
+ if (agentBrowserWanted) {
165
+ if (!silent) logger.step(currentStep++, totalSteps, 'Provisioning agent-browser runtime');
166
+ const abOk = await setupAgentBrowser({ dryRun, silent, cwd: targetDir });
167
+ complete &&= abOk;
168
+ if (!silent && abOk) logger.success('agent-browser runtime ready (CLI + browser)');
169
+ }
170
+
171
+ // Codebase intelligence (Graft)
172
172
  if (!silent) logger.step(currentStep++, totalSteps, 'Configuring codebase intelligence');
173
173
  if (config.codebase.graft && options.graft !== false) {
174
174
  const graftOk = await initGraft(targetDir, { dryRun, silent });
@@ -189,9 +189,10 @@ export async function createProject(
189
189
  );
190
190
  console.log();
191
191
  console.log('Next steps:');
192
- console.log(pc.cyan(` cd ${path.relative(process.cwd(), targetDir) || '.'}`));
192
+ const relativeTarget = path.relative(process.cwd(), targetDir);
193
+ if (relativeTarget) console.log(pc.cyan(` cd ${relativeTarget}`));
193
194
  console.log(pc.cyan(` ${packageManager} install`));
194
- console.log(pc.cyan(' Open the repository in T3 Code'));
195
+ console.log(pc.cyan(' Open the repository in your AI coding agent'));
195
196
  console.log(pc.dim(' Prompt the agent: ') + pc.bold(pc.green('"bootstrap this project"')));
196
197
  console.log();
197
198
  }
package/src/cli/wizard.ts CHANGED
@@ -23,14 +23,12 @@ export interface WizardNewAnswers {
23
23
  preset: PresetType;
24
24
  framework: WebFramework;
25
25
  packageManager: PackageManager;
26
- specWorkflow: boolean;
27
26
  }
28
27
 
29
28
  export interface WizardInitAnswers {
30
29
  preset: PresetType;
31
30
  framework: WebFramework;
32
31
  packageManager: PackageManager;
33
- specWorkflow: boolean;
34
32
  }
35
33
 
36
34
  export async function promptNewProject(defaults?: {
@@ -38,7 +36,6 @@ export async function promptNewProject(defaults?: {
38
36
  preset?: PresetType;
39
37
  framework?: WebFramework;
40
38
  packageManager?: PackageManager;
41
- specWorkflow?: boolean;
42
39
  }): Promise<WizardNewAnswers> {
43
40
  let projectName: string = defaults?.projectName || '';
44
41
  if (!projectName) {
@@ -101,28 +98,6 @@ export async function promptNewProject(defaults?: {
101
98
  framework = assertNotCancelled(res) as WebFramework;
102
99
  }
103
100
 
104
- let specWorkflow = defaults?.specWorkflow;
105
- if (specWorkflow === undefined) {
106
- const res = await p.select({
107
- message: 'Select AI engineering workflow:',
108
- initialValue: 'minimal',
109
- options: [
110
- {
111
- value: 'minimal',
112
- label: 'Standard Workflow (Recommended)',
113
- hint: 'TDD, Code Review, Diagnosing Bugs'
114
- },
115
- {
116
- value: 'spec',
117
- label: 'Spec & Tickets Workflow',
118
- hint: 'Adds to-spec, to-tickets, implement-spec'
119
- }
120
- ]
121
- });
122
- const selected = assertNotCancelled(res);
123
- specWorkflow = selected === 'spec';
124
- }
125
-
126
101
  let packageManager = defaults?.packageManager;
127
102
  if (!packageManager) {
128
103
  const res = await p.select({
@@ -146,8 +121,7 @@ export async function promptNewProject(defaults?: {
146
121
  projectName,
147
122
  preset,
148
123
  framework,
149
- packageManager,
150
- specWorkflow
124
+ packageManager
151
125
  };
152
126
  }
153
127
 
@@ -156,7 +130,6 @@ export async function promptInitProject(defaults?: {
156
130
  preset?: PresetType;
157
131
  framework?: WebFramework;
158
132
  packageManager?: PackageManager;
159
- specWorkflow?: boolean;
160
133
  }): Promise<WizardInitAnswers> {
161
134
  const targetDir = defaults?.targetDir || process.cwd();
162
135
 
@@ -197,28 +170,6 @@ export async function promptInitProject(defaults?: {
197
170
  framework = assertNotCancelled(res) as WebFramework;
198
171
  }
199
172
 
200
- let specWorkflow = defaults?.specWorkflow;
201
- if (specWorkflow === undefined) {
202
- const res = await p.select({
203
- message: 'Select AI engineering workflow:',
204
- initialValue: 'minimal',
205
- options: [
206
- {
207
- value: 'minimal',
208
- label: 'Standard Workflow (Recommended)',
209
- hint: 'TDD, Code Review, Diagnosing Bugs'
210
- },
211
- {
212
- value: 'spec',
213
- label: 'Spec & Tickets Workflow',
214
- hint: 'Adds to-spec, to-tickets, implement-spec'
215
- }
216
- ]
217
- });
218
- const selected = assertNotCancelled(res);
219
- specWorkflow = selected === 'spec';
220
- }
221
-
222
173
  // Auto-detect and preserve existing package manager without prompting
223
174
  let packageManager = defaults?.packageManager;
224
175
  if (!packageManager) {
@@ -243,8 +194,7 @@ export async function promptInitProject(defaults?: {
243
194
  return {
244
195
  preset,
245
196
  framework,
246
- packageManager,
247
- specWorkflow
197
+ packageManager
248
198
  };
249
199
  }
250
200
 
@@ -277,8 +227,7 @@ export async function runInteractiveWizard(): Promise<void> {
277
227
  complete = await createProject(answers.projectName, {
278
228
  preset: answers.preset,
279
229
  framework: answers.framework,
280
- packageManager: answers.packageManager,
281
- specWorkflow: answers.specWorkflow
230
+ packageManager: answers.packageManager
282
231
  });
283
232
  } else {
284
233
  const saved = readProjectConfig(process.cwd());
@@ -291,8 +240,7 @@ export async function runInteractiveWizard(): Promise<void> {
291
240
  complete = await initCurrentDirectory({
292
241
  preset: answers.preset,
293
242
  framework: answers.framework,
294
- packageManager: answers.packageManager,
295
- specWorkflow: answers.specWorkflow
243
+ packageManager: answers.packageManager
296
244
  });
297
245
  }
298
246
  }
@@ -1,21 +1,61 @@
1
- import { AginitConfig, PresetType, WebFramework, PackageManager } from './schema.js';
1
+ import {
2
+ AginitConfig,
3
+ PresetType,
4
+ WebFramework,
5
+ PackageManager,
6
+ SkillSourceConfig
7
+ } from './schema.js';
2
8
 
3
9
  export interface DefaultConfigOptions {
4
10
  framework?: WebFramework;
5
- specWorkflow?: boolean;
6
11
  packageManager?: PackageManager;
7
12
  }
8
13
 
14
+ /**
15
+ * The stable skill set from mattpocock/skills installed by default:
16
+ * every skill in the `engineering` and `productivity` categories.
17
+ *
18
+ * The `misc` (rarely used) and `in-progress` categories are deliberately
19
+ * excluded. Re-evaluate when the upstream repository reshuffles categories.
20
+ */
21
+ export const MATT_POCOCK_SKILLS = [
22
+ // engineering
23
+ 'ask-matt',
24
+ 'code-review',
25
+ 'codebase-design',
26
+ 'diagnosing-bugs',
27
+ 'domain-modeling',
28
+ 'grill-with-docs',
29
+ 'implement',
30
+ 'implement-spec',
31
+ 'improve-codebase-architecture',
32
+ 'pr',
33
+ 'prototype',
34
+ 'research',
35
+ 'retro',
36
+ 'setup-matt-pocock-skills',
37
+ 'tdd',
38
+ 'to-spec',
39
+ 'to-tickets',
40
+ 'triage',
41
+ 'wayfinder',
42
+ 'wizard',
43
+ // productivity
44
+ 'grill-me',
45
+ 'grilling',
46
+ 'handoff',
47
+ 'teach',
48
+ 'to-questionnaire',
49
+ 'wait-what',
50
+ 'writing-for-agents'
51
+ ] as const;
52
+
9
53
  export function getDefaultConfig(
10
54
  name: string,
11
55
  preset: PresetType,
12
56
  options: DefaultConfigOptions = {}
13
57
  ): AginitConfig {
14
- const specWorkflow = !!options.specWorkflow;
15
58
  const packageManager = options.packageManager || 'pnpm';
16
- const mattSkills = specWorkflow
17
- ? ['tdd', 'code-review', 'diagnosing-bugs', 'to-spec', 'to-tickets', 'implement-spec']
18
- : ['tdd', 'code-review', 'diagnosing-bugs'];
19
59
 
20
60
  switch (preset) {
21
61
  case 'web': {
@@ -33,11 +73,18 @@ export function getDefaultConfig(
33
73
  secondary: 'codex'
34
74
  },
35
75
  skills: {
36
- workflow: specWorkflow ? 'spec' : 'minimal',
37
76
  sources: [
38
77
  {
39
78
  package: 'mattpocock/skills',
40
- skills: mattSkills
79
+ skills: [...MATT_POCOCK_SKILLS]
80
+ },
81
+ {
82
+ package: 'blader/humanizer',
83
+ skills: ['humanizer']
84
+ },
85
+ {
86
+ package: 'dietrichgebert/ponytail',
87
+ skills: ['ponytail']
41
88
  },
42
89
  {
43
90
  package: 'pbakaus/impeccable',
@@ -76,11 +123,18 @@ export function getDefaultConfig(
76
123
  secondary: 'codex'
77
124
  },
78
125
  skills: {
79
- workflow: specWorkflow ? 'spec' : 'minimal',
80
126
  sources: [
81
127
  {
82
128
  package: 'mattpocock/skills',
83
- skills: mattSkills
129
+ skills: [...MATT_POCOCK_SKILLS]
130
+ },
131
+ {
132
+ package: 'blader/humanizer',
133
+ skills: ['humanizer']
134
+ },
135
+ {
136
+ package: 'dietrichgebert/ponytail',
137
+ skills: ['ponytail']
84
138
  }
85
139
  ]
86
140
  },
@@ -111,11 +165,18 @@ export function getDefaultConfig(
111
165
  secondary: 'codex'
112
166
  },
113
167
  skills: {
114
- workflow: specWorkflow ? 'spec' : 'minimal',
115
168
  sources: [
116
169
  {
117
170
  package: 'mattpocock/skills',
118
- skills: mattSkills
171
+ skills: [...MATT_POCOCK_SKILLS]
172
+ },
173
+ {
174
+ package: 'blader/humanizer',
175
+ skills: ['humanizer']
176
+ },
177
+ {
178
+ package: 'dietrichgebert/ponytail',
179
+ skills: ['ponytail']
119
180
  }
120
181
  ]
121
182
  },
@@ -135,3 +196,39 @@ export function getDefaultConfig(
135
196
  };
136
197
  }
137
198
  }
199
+
200
+ /** The skill selections that older versions of aginit wrote as defaults. */
201
+ const LEGACY_MATT_SKILL_SELECTIONS: string[][] = [
202
+ ['tdd', 'code-review', 'diagnosing-bugs'],
203
+ ['tdd', 'code-review', 'diagnosing-bugs', 'to-spec', 'to-tickets', 'implement-spec']
204
+ ];
205
+
206
+ function matchesLegacySelection(skills: string[]): boolean {
207
+ return LEGACY_MATT_SKILL_SELECTIONS.some(
208
+ (selection) =>
209
+ selection.length === skills.length && selection.every((skill) => skills.includes(skill))
210
+ );
211
+ }
212
+
213
+ /**
214
+ * Bring a saved `skills` section forward to the current standard: install the
215
+ * full stable Matt Pocock set and drop the retired workflow selector.
216
+ *
217
+ * Only the exact selections aginit used to write are migrated, so a project
218
+ * whose skill list was narrowed by hand keeps the list its author chose.
219
+ */
220
+ export function upgradeLegacySkillConfig(
221
+ skills: AginitConfig['skills']
222
+ ): AginitConfig['skills'] {
223
+ const sources: SkillSourceConfig[] = skills.sources.map((source) =>
224
+ source.package === 'mattpocock/skills' && matchesLegacySelection(source.skills)
225
+ ? { ...source, skills: [...MATT_POCOCK_SKILLS] }
226
+ : source
227
+ );
228
+ const migrated = sources.some((source, index) => source !== skills.sources[index]);
229
+ if (!migrated) return skills;
230
+
231
+ const upgraded: AginitConfig['skills'] = { ...skills, sources };
232
+ delete upgraded.workflow;
233
+ return upgraded;
234
+ }
@@ -18,6 +18,11 @@ export interface AginitConfig {
18
18
  secondary: string;
19
19
  };
20
20
  skills: {
21
+ /**
22
+ * @deprecated Legacy selector from when only a subset of skills was
23
+ * installed. All standard skills are installed now, so this field is no
24
+ * longer written. It is still accepted so existing configs keep loading.
25
+ */
21
26
  workflow?: 'minimal' | 'spec';
22
27
  sources: SkillSourceConfig[];
23
28
  };
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export * from './adapters/skills.js';
9
9
  export * from './adapters/graft.js';
10
10
  export * from './adapters/agents-md.js';
11
11
  export * from './adapters/browser.js';
12
+ export * from './adapters/agent-browser.js';
12
13
  export * from './cli/new.js';
13
14
  export * from './cli/init.js';
14
15
  export * from './cli/doctor.js';