@rasensio/aidlc 0.2.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.
- package/README.md +22 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/update.d.ts +26 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +427 -0
- package/dist/commands/update.js.map +1 -0
- package/package.json +1 -1
- package/skills/01-getting-started.md +4 -0
- package/skills/02-first-activation.md +158 -0
package/README.md
CHANGED
|
@@ -189,6 +189,7 @@ Phase applicability depends on the cycle scope: Full (all phases), Standard (Req
|
|
|
189
189
|
|
|
190
190
|
| Command | Purpose |
|
|
191
191
|
|---------|---------|
|
|
192
|
+
| `aidlc update` | Update CLI and refresh project skills |
|
|
192
193
|
| `aidlc setup` | Interactive setup or update of project configuration |
|
|
193
194
|
| `aidlc discover` | Scan codebase, generate style and architecture context |
|
|
194
195
|
| `aidlc init --platform <id>` | Install skills for a target AI platform |
|
|
@@ -229,6 +230,27 @@ orchestrator: # optional, only for bare-endpoint mode
|
|
|
229
230
|
|
|
230
231
|
Without this file, AIDLC defaults to Micro scope (Implementation + Testing only).
|
|
231
232
|
|
|
233
|
+
## Changelog
|
|
234
|
+
|
|
235
|
+
### 0.3.0
|
|
236
|
+
|
|
237
|
+
**First Activation (brownfield auto-discovery)**
|
|
238
|
+
|
|
239
|
+
- New skill: `02-first-activation.md` — when AIDLC is installed in an existing project, the AI now automatically scans the codebase on first chat interaction. It detects languages, frameworks, conventions, and directory structure, then asks the user about extra context folders (specs, roadmap, design docs, etc.) before writing context docs to `.aidlc/context/`. No terminal round-trip needed after `aidlc init`.
|
|
240
|
+
|
|
241
|
+
**`aidlc update` command**
|
|
242
|
+
|
|
243
|
+
- Self-update: detects which package manager installed AIDLC (npm, pnpm, yarn, bun), checks the npm registry for a newer version, and updates the global CLI.
|
|
244
|
+
- Project refresh: re-runs the install plan for each configured platform, updating skill shims and steering files to match the latest CLI version. Only files whose content changed are rewritten.
|
|
245
|
+
- `--self-only` — update just the CLI, skip project files
|
|
246
|
+
- `--project-only` — refresh project files from the currently installed CLI
|
|
247
|
+
- `--rediscover` — also regenerate `.aidlc/context/` docs (skipped by default to preserve manual edits)
|
|
248
|
+
- `--dry-run` — preview all changes without writing
|
|
249
|
+
|
|
250
|
+
**Getting-started skill update**
|
|
251
|
+
|
|
252
|
+
- The getting-started skill now defers to first-activation when `.aidlc/context/` doesn't exist yet, ensuring discovery runs before lifecycle guidance kicks in.
|
|
253
|
+
|
|
232
254
|
## Contributing
|
|
233
255
|
|
|
234
256
|
### Build and Test
|
package/dist/cli.js
CHANGED
|
@@ -19,6 +19,7 @@ import { registerSetup } from './commands/setup.js';
|
|
|
19
19
|
import { registerAddAction } from './commands/add-action.js';
|
|
20
20
|
import { registerDocs } from './commands/docs.js';
|
|
21
21
|
import { registerReview } from './commands/review.js';
|
|
22
|
+
import { registerUpdate } from './commands/update.js';
|
|
22
23
|
const program = new Command();
|
|
23
24
|
program
|
|
24
25
|
.name('aidlc')
|
|
@@ -35,5 +36,6 @@ registerSetup(program);
|
|
|
35
36
|
registerAddAction(program);
|
|
36
37
|
registerDocs(program);
|
|
37
38
|
registerReview(program);
|
|
39
|
+
registerUpdate(program);
|
|
38
40
|
program.parse();
|
|
39
41
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,oCAAoC,CAAC;KACjD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,oCAAoC,CAAC;KACjD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;AACvB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,cAAc,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc update` command — update the CLI and refresh project skills.
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* 1. Self-update: detect the package manager that installed AIDLC globally,
|
|
6
|
+
* check the npm registry for the latest version, and update if needed.
|
|
7
|
+
* 2. Project refresh: if inside a project with `.aidlc/config.yaml`, re-run
|
|
8
|
+
* `init` for each configured platform to refresh skill shims and steering.
|
|
9
|
+
* 3. Optionally re-run discovery to regenerate context docs (--rediscover).
|
|
10
|
+
*
|
|
11
|
+
* Options:
|
|
12
|
+
* --self-only Only update the CLI, skip project refresh
|
|
13
|
+
* --project-only Only refresh project files from the current CLI
|
|
14
|
+
* --rediscover Also regenerate context docs (.aidlc/context/)
|
|
15
|
+
* --dry-run Show what would change without writing
|
|
16
|
+
*
|
|
17
|
+
* Requirements: 17.1
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import { Command } from 'commander';
|
|
22
|
+
/**
|
|
23
|
+
* Register the `aidlc update` command on the given commander program.
|
|
24
|
+
*/
|
|
25
|
+
export declare function registerUpdate(program: Command): void;
|
|
26
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoYpC;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4BrD"}
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aidlc update` command — update the CLI and refresh project skills.
|
|
3
|
+
*
|
|
4
|
+
* Behavior:
|
|
5
|
+
* 1. Self-update: detect the package manager that installed AIDLC globally,
|
|
6
|
+
* check the npm registry for the latest version, and update if needed.
|
|
7
|
+
* 2. Project refresh: if inside a project with `.aidlc/config.yaml`, re-run
|
|
8
|
+
* `init` for each configured platform to refresh skill shims and steering.
|
|
9
|
+
* 3. Optionally re-run discovery to regenerate context docs (--rediscover).
|
|
10
|
+
*
|
|
11
|
+
* Options:
|
|
12
|
+
* --self-only Only update the CLI, skip project refresh
|
|
13
|
+
* --project-only Only refresh project files from the current CLI
|
|
14
|
+
* --rediscover Also regenerate context docs (.aidlc/context/)
|
|
15
|
+
* --dry-run Show what would change without writing
|
|
16
|
+
*
|
|
17
|
+
* Requirements: 17.1
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import { Command } from 'commander';
|
|
22
|
+
import { execSync } from 'node:child_process';
|
|
23
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
24
|
+
import { join, resolve } from 'node:path';
|
|
25
|
+
import { fileURLToPath } from 'node:url';
|
|
26
|
+
import { parse as parseYaml } from 'yaml';
|
|
27
|
+
import { loadSkills, loadGuidanceLayers } from '../compile/loaders.js';
|
|
28
|
+
import { adapters } from '../compile/adapters/index.js';
|
|
29
|
+
import { executePlan, dryRunPlan } from '../compile/install-plan.js';
|
|
30
|
+
import { scanCodebase, writeContextDocs } from '../discover/scanner.js';
|
|
31
|
+
/**
|
|
32
|
+
* Detect which package manager installed this CLI globally.
|
|
33
|
+
*
|
|
34
|
+
* Strategy:
|
|
35
|
+
* 1. Check the resolved binary path for clues (pnpm, yarn, bun store paths)
|
|
36
|
+
* 2. Check npm_execpath env var (set by npm/pnpm/yarn when running scripts)
|
|
37
|
+
* 3. Check if the binary lives in a known global path pattern
|
|
38
|
+
* 4. Default to npm
|
|
39
|
+
*/
|
|
40
|
+
function detectPackageManager() {
|
|
41
|
+
const execPath = process.env.npm_execpath ?? '';
|
|
42
|
+
const binPath = process.argv[1] ?? '';
|
|
43
|
+
// Check npm_execpath for pnpm/yarn/bun indicators
|
|
44
|
+
if (execPath.includes('pnpm'))
|
|
45
|
+
return 'pnpm';
|
|
46
|
+
if (execPath.includes('yarn'))
|
|
47
|
+
return 'yarn';
|
|
48
|
+
if (execPath.includes('bun'))
|
|
49
|
+
return 'bun';
|
|
50
|
+
// Check the binary install path
|
|
51
|
+
if (binPath.includes('pnpm'))
|
|
52
|
+
return 'pnpm';
|
|
53
|
+
if (binPath.includes('.yarn'))
|
|
54
|
+
return 'yarn';
|
|
55
|
+
if (binPath.includes('.bun'))
|
|
56
|
+
return 'bun';
|
|
57
|
+
// Try to detect from global node_modules path
|
|
58
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
59
|
+
if (thisFile.includes('/pnpm/'))
|
|
60
|
+
return 'pnpm';
|
|
61
|
+
if (thisFile.includes('/.yarn/'))
|
|
62
|
+
return 'yarn';
|
|
63
|
+
return 'npm';
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build the global update command for a given package manager.
|
|
67
|
+
*/
|
|
68
|
+
function buildUpdateCommand(pm, packageName) {
|
|
69
|
+
switch (pm) {
|
|
70
|
+
case 'pnpm':
|
|
71
|
+
return `pnpm update -g ${packageName}`;
|
|
72
|
+
case 'yarn':
|
|
73
|
+
return `yarn global upgrade ${packageName}`;
|
|
74
|
+
case 'bun':
|
|
75
|
+
return `bun update -g ${packageName}`;
|
|
76
|
+
case 'npm':
|
|
77
|
+
default:
|
|
78
|
+
return `npm update -g ${packageName}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Version checking
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
/**
|
|
85
|
+
* Get the currently installed version from package.json.
|
|
86
|
+
*/
|
|
87
|
+
function getCurrentVersion() {
|
|
88
|
+
const packageRoot = getPackageRoot();
|
|
89
|
+
const pkgPath = join(packageRoot, 'package.json');
|
|
90
|
+
try {
|
|
91
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
92
|
+
return pkg.version;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return '0.0.0';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get the package name from package.json.
|
|
100
|
+
*/
|
|
101
|
+
function getPackageName() {
|
|
102
|
+
const packageRoot = getPackageRoot();
|
|
103
|
+
const pkgPath = join(packageRoot, 'package.json');
|
|
104
|
+
try {
|
|
105
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
106
|
+
return pkg.name;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return '@rasensio/aidlc';
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Fetch the latest version from the npm registry.
|
|
114
|
+
* Returns null if the registry is unreachable.
|
|
115
|
+
*/
|
|
116
|
+
function fetchLatestVersion(packageName) {
|
|
117
|
+
try {
|
|
118
|
+
const output = execSync(`npm view ${packageName} dist-tags.latest`, {
|
|
119
|
+
encoding: 'utf8',
|
|
120
|
+
timeout: 15_000,
|
|
121
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
122
|
+
});
|
|
123
|
+
return output.trim() || null;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Simple semver comparison: returns true if `a` < `b`.
|
|
131
|
+
*/
|
|
132
|
+
function isOlderThan(a, b) {
|
|
133
|
+
const partsA = a.split('.').map(Number);
|
|
134
|
+
const partsB = b.split('.').map(Number);
|
|
135
|
+
for (let i = 0; i < 3; i++) {
|
|
136
|
+
const numA = partsA[i] ?? 0;
|
|
137
|
+
const numB = partsB[i] ?? 0;
|
|
138
|
+
if (numA < numB)
|
|
139
|
+
return true;
|
|
140
|
+
if (numA > numB)
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// Helpers
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
/**
|
|
149
|
+
* Resolve the package root directory.
|
|
150
|
+
*/
|
|
151
|
+
function getPackageRoot() {
|
|
152
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
153
|
+
return resolve(thisFile, '..', '..', '..');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Load the project's .aidlc/config.yaml to get configured platforms.
|
|
157
|
+
*/
|
|
158
|
+
function loadProjectConfig(projectRoot) {
|
|
159
|
+
const configPath = join(projectRoot, '.aidlc', 'config.yaml');
|
|
160
|
+
if (!existsSync(configPath))
|
|
161
|
+
return null;
|
|
162
|
+
try {
|
|
163
|
+
const raw = readFileSync(configPath, 'utf8');
|
|
164
|
+
const parsed = parseYaml(raw);
|
|
165
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
166
|
+
return null;
|
|
167
|
+
return parsed;
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Load a capability map for a platform from the package's capabilities/ dir.
|
|
175
|
+
*/
|
|
176
|
+
function loadCapabilityMap(platform, packageRoot) {
|
|
177
|
+
const filePath = join(packageRoot, 'capabilities', `${platform}.yaml`);
|
|
178
|
+
if (!existsSync(filePath))
|
|
179
|
+
return null;
|
|
180
|
+
try {
|
|
181
|
+
const raw = readFileSync(filePath, 'utf8');
|
|
182
|
+
const parsed = parseYaml(raw);
|
|
183
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
184
|
+
return null;
|
|
185
|
+
return parsed;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Build the ProjectContext for a given project root.
|
|
193
|
+
*/
|
|
194
|
+
function buildProjectContext(projectRoot) {
|
|
195
|
+
const contextDir = join(projectRoot, '.aidlc', 'context');
|
|
196
|
+
const guidanceDir = join(projectRoot, '.aidlc', 'guidance');
|
|
197
|
+
const contextDocs = {};
|
|
198
|
+
if (existsSync(contextDir)) {
|
|
199
|
+
try {
|
|
200
|
+
for (const entry of readdirSync(contextDir)) {
|
|
201
|
+
const name = entry.replace(/\.[^.]+$/, '');
|
|
202
|
+
contextDocs[name] = entry;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// proceed with empty
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const guidanceLayers = {};
|
|
210
|
+
if (existsSync(guidanceDir)) {
|
|
211
|
+
const loaded = loadGuidanceLayers(guidanceDir);
|
|
212
|
+
for (const layer of loaded.layers) {
|
|
213
|
+
guidanceLayers[layer.name] = `${layer.name}.md`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return { root: projectRoot, contextDocs, guidanceLayers };
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Perform the CLI self-update.
|
|
220
|
+
*/
|
|
221
|
+
function selfUpdate(dryRun) {
|
|
222
|
+
const currentVersion = getCurrentVersion();
|
|
223
|
+
const packageName = getPackageName();
|
|
224
|
+
process.stderr.write('Checking for updates...\n');
|
|
225
|
+
const latestVersion = fetchLatestVersion(packageName);
|
|
226
|
+
if (latestVersion === null) {
|
|
227
|
+
return {
|
|
228
|
+
updated: false,
|
|
229
|
+
from: currentVersion,
|
|
230
|
+
to: null,
|
|
231
|
+
skipped: true,
|
|
232
|
+
reason: 'unable to reach npm registry',
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
if (!isOlderThan(currentVersion, latestVersion)) {
|
|
236
|
+
return {
|
|
237
|
+
updated: false,
|
|
238
|
+
from: currentVersion,
|
|
239
|
+
to: latestVersion,
|
|
240
|
+
skipped: true,
|
|
241
|
+
reason: 'already up to date',
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
const pm = detectPackageManager();
|
|
245
|
+
const cmd = buildUpdateCommand(pm, packageName);
|
|
246
|
+
if (dryRun) {
|
|
247
|
+
process.stdout.write(`Would run: ${cmd}\n`);
|
|
248
|
+
process.stdout.write(` ${currentVersion} → ${latestVersion}\n`);
|
|
249
|
+
return { updated: false, from: currentVersion, to: latestVersion, skipped: false };
|
|
250
|
+
}
|
|
251
|
+
process.stderr.write(`Updating CLI via ${pm}...\n`);
|
|
252
|
+
process.stderr.write(` ${currentVersion} → ${latestVersion}\n`);
|
|
253
|
+
try {
|
|
254
|
+
execSync(cmd, { stdio: 'inherit', timeout: 60_000 });
|
|
255
|
+
return { updated: true, from: currentVersion, to: latestVersion, skipped: false };
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
process.stderr.write(`warning: update command failed: ${cmd}\n`);
|
|
259
|
+
process.stderr.write('You may need to run it manually with elevated permissions.\n');
|
|
260
|
+
return {
|
|
261
|
+
updated: false,
|
|
262
|
+
from: currentVersion,
|
|
263
|
+
to: latestVersion,
|
|
264
|
+
skipped: true,
|
|
265
|
+
reason: 'update command failed (may require sudo)',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Refresh project skills by re-running the install plan for each configured platform.
|
|
271
|
+
*/
|
|
272
|
+
function refreshProject(projectRoot, dryRun) {
|
|
273
|
+
const config = loadProjectConfig(projectRoot);
|
|
274
|
+
if (!config) {
|
|
275
|
+
process.stderr.write('No .aidlc/config.yaml found — skipping project refresh.\n');
|
|
276
|
+
process.stderr.write('Run `aidlc setup` first to configure this project.\n');
|
|
277
|
+
return { filesWritten: [], filesSkipped: [], warnings: [], platforms: [] };
|
|
278
|
+
}
|
|
279
|
+
const platforms = config.platforms ?? [];
|
|
280
|
+
if (platforms.length === 0) {
|
|
281
|
+
process.stderr.write('No platforms configured — skipping project refresh.\n');
|
|
282
|
+
return { filesWritten: [], filesSkipped: [], warnings: [], platforms: [] };
|
|
283
|
+
}
|
|
284
|
+
const packageRoot = getPackageRoot();
|
|
285
|
+
const skillsDir = join(packageRoot, 'skills');
|
|
286
|
+
const skills = loadSkills(skillsDir);
|
|
287
|
+
const allWritten = [];
|
|
288
|
+
const allSkipped = [];
|
|
289
|
+
const allWarnings = [];
|
|
290
|
+
for (const platform of platforms) {
|
|
291
|
+
const adapter = adapters.get(platform);
|
|
292
|
+
if (!adapter) {
|
|
293
|
+
allWarnings.push(`unknown platform '${platform}' in config — skipped`);
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
const caps = loadCapabilityMap(platform, packageRoot);
|
|
297
|
+
const ctx = buildProjectContext(projectRoot);
|
|
298
|
+
const plan = adapter.plan(skills, caps, ctx);
|
|
299
|
+
allWarnings.push(...plan.warnings);
|
|
300
|
+
if (dryRun) {
|
|
301
|
+
const report = dryRunPlan(plan, projectRoot);
|
|
302
|
+
allWritten.push(...report.filesWritten);
|
|
303
|
+
allSkipped.push(...report.filesSkipped);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const report = executePlan(plan, projectRoot);
|
|
307
|
+
allWritten.push(...report.filesWritten);
|
|
308
|
+
allSkipped.push(...report.filesSkipped);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return { filesWritten: allWritten, filesSkipped: allSkipped, warnings: allWarnings, platforms };
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Re-run codebase discovery to regenerate .aidlc/context/ docs.
|
|
315
|
+
*/
|
|
316
|
+
function rediscover(projectRoot, dryRun) {
|
|
317
|
+
if (dryRun) {
|
|
318
|
+
process.stdout.write('Would regenerate .aidlc/context/ docs\n');
|
|
319
|
+
return { docsWritten: ['.aidlc/context/style-guide.md', '.aidlc/context/architecture.md'] };
|
|
320
|
+
}
|
|
321
|
+
const result = scanCodebase(projectRoot);
|
|
322
|
+
const docPaths = writeContextDocs(projectRoot, result);
|
|
323
|
+
return { docsWritten: docPaths };
|
|
324
|
+
}
|
|
325
|
+
// ---------------------------------------------------------------------------
|
|
326
|
+
// Command registration
|
|
327
|
+
// ---------------------------------------------------------------------------
|
|
328
|
+
/**
|
|
329
|
+
* Register the `aidlc update` command on the given commander program.
|
|
330
|
+
*/
|
|
331
|
+
export function registerUpdate(program) {
|
|
332
|
+
program
|
|
333
|
+
.command('update')
|
|
334
|
+
.description('Update the AIDLC CLI and refresh project skills')
|
|
335
|
+
.option('--self-only', 'Only update the CLI globally, skip project file refresh')
|
|
336
|
+
.option('--project-only', 'Only refresh project files from the currently installed CLI')
|
|
337
|
+
.option('--rediscover', 'Also regenerate context docs in .aidlc/context/')
|
|
338
|
+
.option('--dry-run', 'Show what would change without writing anything')
|
|
339
|
+
.addHelpText('after', `
|
|
340
|
+
Examples:
|
|
341
|
+
aidlc update Update CLI + refresh project skills
|
|
342
|
+
aidlc update --self-only Just update the global CLI package
|
|
343
|
+
aidlc update --project-only Just refresh .kiro/skills/ from current CLI
|
|
344
|
+
aidlc update --rediscover Also regenerate .aidlc/context/ docs
|
|
345
|
+
aidlc update --dry-run Preview changes without applying them
|
|
346
|
+
|
|
347
|
+
How it works:
|
|
348
|
+
1. Detects your package manager (npm, pnpm, yarn, bun)
|
|
349
|
+
2. Checks the npm registry for a newer version
|
|
350
|
+
3. Updates the CLI if a newer version is available
|
|
351
|
+
4. Re-runs the install plan for each configured platform
|
|
352
|
+
to refresh skill shims and steering files
|
|
353
|
+
5. Skips .aidlc/context/ docs unless --rediscover is passed
|
|
354
|
+
(context docs may have been manually edited)
|
|
355
|
+
`)
|
|
356
|
+
.action((opts) => {
|
|
357
|
+
runUpdate(opts);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
// Core logic
|
|
362
|
+
// ---------------------------------------------------------------------------
|
|
363
|
+
function runUpdate(opts) {
|
|
364
|
+
const projectRoot = process.cwd();
|
|
365
|
+
const dryRun = opts.dryRun ?? false;
|
|
366
|
+
if (dryRun) {
|
|
367
|
+
process.stdout.write('Dry run — no changes will be made.\n\n');
|
|
368
|
+
}
|
|
369
|
+
// --- Self-update ---
|
|
370
|
+
if (!opts.projectOnly) {
|
|
371
|
+
const selfResult = selfUpdate(dryRun);
|
|
372
|
+
if (selfResult.skipped) {
|
|
373
|
+
process.stdout.write(`CLI: ${selfResult.from} (${selfResult.reason})\n`);
|
|
374
|
+
}
|
|
375
|
+
else if (selfResult.updated) {
|
|
376
|
+
process.stdout.write(`CLI: ${selfResult.from} → ${selfResult.to}\n`);
|
|
377
|
+
}
|
|
378
|
+
else if (dryRun && selfResult.to) {
|
|
379
|
+
process.stdout.write(`CLI: would update ${selfResult.from} → ${selfResult.to}\n`);
|
|
380
|
+
}
|
|
381
|
+
process.stdout.write('\n');
|
|
382
|
+
}
|
|
383
|
+
// --- Project refresh ---
|
|
384
|
+
if (!opts.selfOnly) {
|
|
385
|
+
process.stderr.write('Refreshing project skills...\n');
|
|
386
|
+
const refreshResult = refreshProject(projectRoot, dryRun);
|
|
387
|
+
for (const w of refreshResult.warnings) {
|
|
388
|
+
process.stderr.write(` warning: ${w}\n`);
|
|
389
|
+
}
|
|
390
|
+
if (refreshResult.filesWritten.length > 0) {
|
|
391
|
+
const verb = dryRun ? 'Would update' : 'Updated';
|
|
392
|
+
process.stdout.write(`${verb}:\n`);
|
|
393
|
+
for (const f of refreshResult.filesWritten) {
|
|
394
|
+
process.stdout.write(` + ${f}\n`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (refreshResult.filesSkipped.length > 0) {
|
|
398
|
+
process.stdout.write(`Unchanged:\n`);
|
|
399
|
+
for (const f of refreshResult.filesSkipped) {
|
|
400
|
+
process.stdout.write(` = ${f}\n`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (refreshResult.platforms.length > 0) {
|
|
404
|
+
process.stdout.write(`\nProject: ${refreshResult.filesWritten.length} file(s) ${dryRun ? 'would be ' : ''}updated, ` +
|
|
405
|
+
`${refreshResult.filesSkipped.length} unchanged ` +
|
|
406
|
+
`(${refreshResult.platforms.join(', ')})\n`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
// --- Rediscover ---
|
|
410
|
+
if (opts.rediscover) {
|
|
411
|
+
process.stdout.write('\n');
|
|
412
|
+
process.stderr.write('Regenerating context docs...\n');
|
|
413
|
+
const discoverResult = rediscover(projectRoot, dryRun);
|
|
414
|
+
const verb = dryRun ? 'Would write' : 'Wrote';
|
|
415
|
+
for (const doc of discoverResult.docsWritten) {
|
|
416
|
+
process.stdout.write(` ${verb}: ${doc}\n`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// --- Final summary ---
|
|
420
|
+
if (dryRun) {
|
|
421
|
+
process.stdout.write('\nNo changes were made (--dry-run).\n');
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
process.stdout.write('\nDone.\n');
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -7,6 +7,10 @@ trigger: When the user asks how to get started, how to use the framework, or ask
|
|
|
7
7
|
---
|
|
8
8
|
# Getting Started with AIDLC
|
|
9
9
|
|
|
10
|
+
## Pre-condition: First Activation
|
|
11
|
+
|
|
12
|
+
Before responding with this skill, check whether `.aidlc/context/` exists and contains at least one `.md` file. If it does NOT, defer to the **aidlc-first-activation** skill instead — it will scan the project, build context docs, and then hand control back to the user's original request. Do not proceed with getting-started guidance until first-activation has completed.
|
|
13
|
+
|
|
10
14
|
## When to Activate
|
|
11
15
|
|
|
12
16
|
Respond using this skill when the user asks any of the following:
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aidlc-first-activation
|
|
3
|
+
description: Auto-discovers a brownfield project on first activation — scans codebase, asks about extra context folders, writes context docs
|
|
4
|
+
phase: ideation
|
|
5
|
+
priority: 98
|
|
6
|
+
trigger: When AIDLC is installed but `.aidlc/context/` does not exist or contains no files
|
|
7
|
+
---
|
|
8
|
+
# First Activation — Project Discovery
|
|
9
|
+
|
|
10
|
+
## Purpose
|
|
11
|
+
|
|
12
|
+
When AIDLC is freshly installed in an existing (brownfield) project, this skill runs once to build project context automatically. It replaces the need for the user to run `aidlc discover` from the terminal.
|
|
13
|
+
|
|
14
|
+
## Activation Condition
|
|
15
|
+
|
|
16
|
+
Activate this skill **before any other AIDLC skill** when ALL of the following are true:
|
|
17
|
+
|
|
18
|
+
1. AIDLC skills are installed (`.aidlc/skills/` exists)
|
|
19
|
+
2. The context directory is missing or empty (`.aidlc/context/` does not exist, or contains no `.md` files)
|
|
20
|
+
3. The user has just sent a message (any message — they may be asking to fix a bug, add a feature, etc.)
|
|
21
|
+
|
|
22
|
+
If `.aidlc/context/` already contains at least one `.md` file, skip this skill entirely and proceed with the user's request using the appropriate skill.
|
|
23
|
+
|
|
24
|
+
## Behavior
|
|
25
|
+
|
|
26
|
+
### Step 1: Acknowledge and Scan
|
|
27
|
+
|
|
28
|
+
Tell the user briefly that you're indexing the project for the first time. Keep it short — don't block them with a wall of text.
|
|
29
|
+
|
|
30
|
+
Example: *"First time here — let me scan the project quickly so I have context."*
|
|
31
|
+
|
|
32
|
+
Then perform a lightweight scan:
|
|
33
|
+
|
|
34
|
+
1. **Read manifest files** at the project root: `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `pom.xml`, `build.gradle`, `Gemfile`, or equivalent.
|
|
35
|
+
2. **List top-level directories** to understand the project structure.
|
|
36
|
+
3. **Sample 3-5 source files** from the primary source directory to detect:
|
|
37
|
+
- Indentation style (tabs, 2-space, 4-space)
|
|
38
|
+
- Naming convention (camelCase, snake_case, PascalCase)
|
|
39
|
+
- Import style (grouped vs ungrouped)
|
|
40
|
+
4. **Identify the tech stack**: language(s), frameworks, test runner, build tool, linter.
|
|
41
|
+
|
|
42
|
+
### Step 2: Ask About Extra Context Folders
|
|
43
|
+
|
|
44
|
+
After scanning, ask the user:
|
|
45
|
+
|
|
46
|
+
> "I've got the basics — [summarize: language, framework, structure in one line].
|
|
47
|
+
>
|
|
48
|
+
> Beyond the source code, are there any folders I should be aware of for ongoing context? For example: specs, roadmap, architecture decisions, API schemas, design docs, etc."
|
|
49
|
+
|
|
50
|
+
Wait for the user's answer. Common examples:
|
|
51
|
+
- `specs/`, `docs/`, `roadmap/`, `architecture/`, `adr/`, `design/`, `api/`
|
|
52
|
+
- The user might also point to specific files like `ARCHITECTURE.md` or `openapi.yaml`
|
|
53
|
+
|
|
54
|
+
If the user says "no" or "that's it," proceed without extra folders.
|
|
55
|
+
|
|
56
|
+
### Step 3: Read Extra Context
|
|
57
|
+
|
|
58
|
+
For each folder or file the user mentions:
|
|
59
|
+
1. List its contents (non-recursive, top level only for folders)
|
|
60
|
+
2. Read key files (prefer: index files, READMEs, YAML/JSON schemas, markdown docs)
|
|
61
|
+
3. Summarize what you found — don't copy entire documents verbatim
|
|
62
|
+
|
|
63
|
+
Cap this step: read at most 10 files total from extra context folders. If there's more, note what was skipped and tell the user they can point you at specific files later.
|
|
64
|
+
|
|
65
|
+
### Step 4: Write Context Documents
|
|
66
|
+
|
|
67
|
+
Create `.aidlc/context/` and write:
|
|
68
|
+
|
|
69
|
+
#### `style-guide.md`
|
|
70
|
+
```markdown
|
|
71
|
+
---
|
|
72
|
+
generated_by: aidlc-first-activation
|
|
73
|
+
generated_at: <ISO 8601 UTC>
|
|
74
|
+
---
|
|
75
|
+
# Style Guide
|
|
76
|
+
|
|
77
|
+
## Languages
|
|
78
|
+
<table of languages with approximate file counts>
|
|
79
|
+
|
|
80
|
+
## Conventions
|
|
81
|
+
- Indentation: <detected>
|
|
82
|
+
- Naming: <detected>
|
|
83
|
+
- Import style: <detected>
|
|
84
|
+
|
|
85
|
+
## Frameworks & Tools
|
|
86
|
+
<list of detected frameworks, test runners, build tools>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### `architecture.md`
|
|
90
|
+
```markdown
|
|
91
|
+
---
|
|
92
|
+
generated_by: aidlc-first-activation
|
|
93
|
+
generated_at: <ISO 8601 UTC>
|
|
94
|
+
---
|
|
95
|
+
# Architecture Overview
|
|
96
|
+
|
|
97
|
+
## Tech Stack
|
|
98
|
+
<primary languages and frameworks>
|
|
99
|
+
|
|
100
|
+
## Directory Structure
|
|
101
|
+
<role mapping of top-level directories>
|
|
102
|
+
|
|
103
|
+
## Entry Points
|
|
104
|
+
<detected entry points>
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
<config approach: env vars, YAML, etc.>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### `project-knowledge.md` (only if the user provided extra folders)
|
|
111
|
+
```markdown
|
|
112
|
+
---
|
|
113
|
+
generated_by: aidlc-first-activation
|
|
114
|
+
generated_at: <ISO 8601 UTC>
|
|
115
|
+
source_paths:
|
|
116
|
+
- <path1>
|
|
117
|
+
- <path2>
|
|
118
|
+
---
|
|
119
|
+
# Project Knowledge
|
|
120
|
+
|
|
121
|
+
## Sources
|
|
122
|
+
<list of folders/files the user pointed to>
|
|
123
|
+
|
|
124
|
+
## Summary
|
|
125
|
+
|
|
126
|
+
### <Folder/File 1 Name>
|
|
127
|
+
<2-5 sentence summary of what's in there and what's relevant>
|
|
128
|
+
|
|
129
|
+
### <Folder/File 2 Name>
|
|
130
|
+
<2-5 sentence summary>
|
|
131
|
+
|
|
132
|
+
## Key References
|
|
133
|
+
<specific files worth reading in full when working on related areas>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Step 5: Confirm and Continue
|
|
137
|
+
|
|
138
|
+
After writing the context docs, briefly confirm:
|
|
139
|
+
|
|
140
|
+
> "Done — indexed the project. Context saved to `.aidlc/context/`. Now, back to your request..."
|
|
141
|
+
|
|
142
|
+
Then **immediately proceed** with whatever the user originally asked. Do not make them repeat themselves. Their original message is still the active task — discovery was a transparent preamble.
|
|
143
|
+
|
|
144
|
+
## Important Notes
|
|
145
|
+
|
|
146
|
+
- **This skill runs exactly once per project.** After context docs are written, it never triggers again.
|
|
147
|
+
- **Don't over-scan.** This is a lightweight pass, not a full AST analysis. 3-5 sampled files is enough for style detection.
|
|
148
|
+
- **Don't block the user.** The scan should feel like a 10-second preamble, not a separate workflow. If the project is huge, just scan what you can quickly and note gaps.
|
|
149
|
+
- **Respect .gitignore patterns.** Don't scan `node_modules/`, `dist/`, `build/`, `.git/`, etc.
|
|
150
|
+
- **Extra context is optional.** If the user says "nah, just the code" — that's fine. Skip `project-knowledge.md`.
|
|
151
|
+
- **The user's original request takes priority.** Discovery enables better answers but must not derail the conversation.
|
|
152
|
+
|
|
153
|
+
## Exit Criteria
|
|
154
|
+
|
|
155
|
+
- `.aidlc/context/style-guide.md` exists with detected conventions
|
|
156
|
+
- `.aidlc/context/architecture.md` exists with structure overview
|
|
157
|
+
- `.aidlc/context/project-knowledge.md` exists (if extra folders were provided)
|
|
158
|
+
- The user's original request is being addressed (not abandoned)
|