@ai-plugin-marketplace/core 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/dist/core.d.ts +51 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pipeline/init-template.d.ts +16 -5
- package/dist/pipeline/init-template.d.ts.map +1 -1
- package/dist/pipeline/init-template.js +65 -21
- package/dist/pipeline/init-template.js.map +1 -1
- package/dist/pipeline/init.d.ts +17 -14
- package/dist/pipeline/init.d.ts.map +1 -1
- package/dist/pipeline/init.js +23 -15
- package/dist/pipeline/init.js.map +1 -1
- package/dist/pipeline/operations.d.ts +11 -1
- package/dist/pipeline/operations.d.ts.map +1 -1
- package/dist/pipeline/operations.js +16 -0
- package/dist/pipeline/operations.js.map +1 -1
- package/dist/pipeline/scaffold-refresh.d.ts +80 -0
- package/dist/pipeline/scaffold-refresh.d.ts.map +1 -0
- package/dist/pipeline/scaffold-refresh.js +152 -0
- package/dist/pipeline/scaffold-refresh.js.map +1 -0
- package/dist/pipeline/types.d.ts +38 -0
- package/dist/pipeline/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/core.d.ts
CHANGED
|
@@ -287,6 +287,13 @@ export declare interface InitOptions {
|
|
|
287
287
|
* directory.
|
|
288
288
|
*/
|
|
289
289
|
name?: string;
|
|
290
|
+
/**
|
|
291
|
+
* Version of `@ai-plugin-marketplace/cli` to pin the generated `package.json`'s `cli`
|
|
292
|
+
* dev dependency to (as `^<cliVersion>`). The cli entrypoint supplies its own version here; cli
|
|
293
|
+
* and core ship independently and may differ (e.g. `cli 0.1.1` ships with `core 0.2.0`). When
|
|
294
|
+
* omitted, falls back to core's own version (the historical lockstep assumption).
|
|
295
|
+
*/
|
|
296
|
+
cliVersion?: string;
|
|
290
297
|
}
|
|
291
298
|
|
|
292
299
|
/**
|
|
@@ -332,6 +339,50 @@ export declare interface MigrateResult {
|
|
|
332
339
|
filesChanged: string[];
|
|
333
340
|
}
|
|
334
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Options for {@link refreshScaffold}.
|
|
344
|
+
*
|
|
345
|
+
* @public
|
|
346
|
+
*/
|
|
347
|
+
export declare interface RefreshOptions {
|
|
348
|
+
/**
|
|
349
|
+
* Overwrite toolkit-owned scaffold files even when their on-disk content has diverged from what
|
|
350
|
+
* the toolkit last wrote (i.e. the user edited them). Without this, diverged files are reported
|
|
351
|
+
* as conflicts and left untouched.
|
|
352
|
+
*/
|
|
353
|
+
force?: boolean;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Per-file outcome of a {@link refreshScaffold} run. Returned (one per managed scaffold file) so
|
|
358
|
+
* the CLI can report what changed without re-deriving it.
|
|
359
|
+
*
|
|
360
|
+
* @public
|
|
361
|
+
*/
|
|
362
|
+
export declare interface RefreshOutcome {
|
|
363
|
+
/** Repo-relative POSIX path of the managed scaffold file. */
|
|
364
|
+
path: string;
|
|
365
|
+
/**
|
|
366
|
+
* - `updated` — content changed and was rewritten (file was pristine or `--force`).
|
|
367
|
+
* - `unchanged` — already matched the current render; nothing written.
|
|
368
|
+
* - `recreated` — file was missing and was written from the render.
|
|
369
|
+
* - `conflict` — on-disk content diverged from the recorded hash; left untouched (no `--force`).
|
|
370
|
+
* - `overwritten` — diverged but rewritten because `--force` was set.
|
|
371
|
+
*/
|
|
372
|
+
status: 'updated' | 'unchanged' | 'recreated' | 'conflict' | 'overwritten';
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Refresh the toolkit-owned scaffold files (CI workflow, `.gitignore`) of an existing marketplace
|
|
377
|
+
* repo at `targetDir` to match the installed tooling — the upgrade path after
|
|
378
|
+
* `pnpm up @ai-plugin-marketplace/*`. Guarded by the `.aipm/scaffold.json` content-hash sidecar:
|
|
379
|
+
* user-modified files are reported as conflicts and left untouched unless `opts.force` is set.
|
|
380
|
+
* Returns one outcome per managed file; never rejects on conflict.
|
|
381
|
+
*
|
|
382
|
+
* @public
|
|
383
|
+
*/
|
|
384
|
+
export declare function refreshScaffold(targetDir: string, opts?: RefreshOptions): Promise<RefreshOutcome[]>;
|
|
385
|
+
|
|
335
386
|
/**
|
|
336
387
|
* Scaffold a new plugin under the cwd's configured plugins root (`<cwd>/plugins/<name>` by
|
|
337
388
|
* default, or the relocated `pluginsRoot` from an `aipm.repo.ts`). The plugins directory is
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export { defineConfig, defineRepoConfig, defineWorkspace } from './config.js';
|
|
12
12
|
export type { AipmConfig, AipmConfigInput, AipmRepoConfig, AipmRepoConfigInput, AipmWorkspace, AipmWorkspaceInput, } from './config.js';
|
|
13
|
-
export { build, validate, scaffold, init, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
|
|
14
|
-
export type { TargetId, BuildOptions, BuildResult, GeneratedFile, ValidateOptions, ValidationResult, Finding, FindingCode, ScaffoldOptions, InitOptions, MigrateOptions, MigrateResult, SupportReport, } from './pipeline/types.js';
|
|
13
|
+
export { build, validate, scaffold, init, refreshScaffold, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
|
|
14
|
+
export type { TargetId, BuildOptions, BuildResult, GeneratedFile, ValidateOptions, ValidationResult, Finding, FindingCode, ScaffoldOptions, InitOptions, RefreshOptions, RefreshOutcome, MigrateOptions, MigrateResult, SupportReport, } from './pipeline/types.js';
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,eAAe,EACf,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
* @packageDocumentation
|
|
10
10
|
*/
|
|
11
11
|
export { defineConfig, defineRepoConfig, defineWorkspace } from './config.js';
|
|
12
|
-
export { build, validate, scaffold, init, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
|
|
12
|
+
export { build, validate, scaffold, init, refreshScaffold, migrate, checkSupport, addTarget, listTargets, } from './pipeline/operations.js';
|
|
13
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9E,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9E,OAAO,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,OAAO,EACP,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,0BAA0B,CAAC"}
|
|
@@ -21,13 +21,24 @@ export interface InitFile {
|
|
|
21
21
|
/** Full file contents, including a trailing newline. */
|
|
22
22
|
content: string;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Toolkit-owned **scaffold** files that `aipm init --refresh` keeps in sync with the installed
|
|
26
|
+
* tooling: the CI workflow and `.gitignore`. These are pure tooling recipes — their content is
|
|
27
|
+
* independent of the repo name and the pinned toolkit version, so refresh can re-render them with
|
|
28
|
+
* no inputs and compare byte-for-byte. (Files with repo identity or user content — `package.json`,
|
|
29
|
+
* `aipm.workspace.ts`, `README.md`, plugins, `aipm build` output — are deliberately NOT here.)
|
|
30
|
+
*
|
|
31
|
+
* Output is deterministic and stably ordered.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildManagedScaffoldFiles(): InitFile[];
|
|
24
34
|
/**
|
|
25
35
|
* Build the complete, deterministic seed file set for a consumer repo named `name`, pinning the
|
|
26
|
-
*
|
|
36
|
+
* `cli`/`core` dev dependencies to carets of `cliVersion`/`coreVersion` respectively.
|
|
27
37
|
*
|
|
28
|
-
* The set mirrors §3.2: `package.json`,
|
|
29
|
-
*
|
|
30
|
-
*
|
|
38
|
+
* The set mirrors §3.2: `package.json`, the {@link buildManagedScaffoldFiles managed scaffold
|
|
39
|
+
* files} (`.gitignore`, CI workflow), `README.md`, both repo-root marketplace registries, and an
|
|
40
|
+
* empty `plugins/` (seeded with `.gitkeep` so the directory is tracked). Output is a pure function
|
|
41
|
+
* of the inputs — stable ordering, no timestamps.
|
|
31
42
|
*/
|
|
32
|
-
export declare function buildInitFiles(name: string,
|
|
43
|
+
export declare function buildInitFiles(name: string, cliVersion: string, coreVersion: string): InitFile[];
|
|
33
44
|
//# sourceMappingURL=init-template.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-template.d.ts","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"init-template.d.ts","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH,gGAAgG;AAChG,MAAM,WAAW,QAAQ;IACvB,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;CACjB;AAqID;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,IAAI,QAAQ,EAAE,CAKtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,QAAQ,EAAE,CAShG"}
|
|
@@ -17,33 +17,40 @@
|
|
|
17
17
|
const json = String.raw;
|
|
18
18
|
const md = String.raw;
|
|
19
19
|
const yaml = String.raw;
|
|
20
|
+
/**
|
|
21
|
+
* pnpm version pinned in the generated `package.json#packageManager`. The CI workflow reads the
|
|
22
|
+
* pnpm version from this field (it runs `pnpm/action-setup` without a hard-coded version), so the
|
|
23
|
+
* two stay in sync. Bumped deliberately when the recommended pnpm baseline moves.
|
|
24
|
+
*/
|
|
25
|
+
const PACKAGE_MANAGER = 'pnpm@10.30.3';
|
|
20
26
|
/**
|
|
21
27
|
* The `package.json` for a generated consumer repo.
|
|
22
28
|
*
|
|
23
29
|
* - `private: true` — a plugin repo is never published to npm; only its plugins ship to registries.
|
|
24
30
|
* - `type: 'module'` — the toolkit is ESM-only (§8.1), and `aipm.config.ts` files are ESM.
|
|
31
|
+
* - `packageManager` pins pnpm; the CI workflow reads the pnpm version from here.
|
|
25
32
|
* - `scripts` call `aipm` directly (it is on PATH via the dev dependency's bin).
|
|
26
|
-
* -
|
|
27
|
-
*
|
|
33
|
+
* - `cli` provides the `aipm` binary; `core` provides `defineConfig`/`defineWorkspace` for each
|
|
34
|
+
* plugin's `aipm.config.ts` (§6.1). They ship independently and may differ (`cli 0.1.1` ships
|
|
35
|
+
* with `core 0.2.0`), so each is pinned to a caret of its own version; authors upgrade both via
|
|
36
|
+
* `pnpm up` (§11 contract).
|
|
28
37
|
*
|
|
29
38
|
* Emitted as 2-space JSON with a trailing newline to match the repo's formatting conventions.
|
|
30
39
|
*/
|
|
31
|
-
function renderPackageJson(name,
|
|
40
|
+
function renderPackageJson(name, cliVersion, coreVersion) {
|
|
32
41
|
const pkg = {
|
|
33
42
|
name,
|
|
34
43
|
private: true,
|
|
35
44
|
type: 'module',
|
|
45
|
+
packageManager: PACKAGE_MANAGER,
|
|
36
46
|
scripts: {
|
|
37
47
|
build: 'aipm build',
|
|
38
48
|
check: 'aipm validate',
|
|
39
49
|
scaffold: 'aipm scaffold',
|
|
40
50
|
},
|
|
41
51
|
devDependencies: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// version and upgraded together via `pnpm up`.
|
|
45
|
-
'@ai-plugin-marketplace/cli': `^${toolkitVersion}`,
|
|
46
|
-
'@ai-plugin-marketplace/core': `^${toolkitVersion}`,
|
|
52
|
+
'@ai-plugin-marketplace/cli': `^${cliVersion}`,
|
|
53
|
+
'@ai-plugin-marketplace/core': `^${coreVersion}`,
|
|
47
54
|
},
|
|
48
55
|
};
|
|
49
56
|
return `${JSON.stringify(pkg, null, 2)}\n`;
|
|
@@ -95,21 +102,43 @@ function renderCiWorkflow() {
|
|
|
95
102
|
|
|
96
103
|
on:
|
|
97
104
|
push:
|
|
105
|
+
branches: [main]
|
|
98
106
|
pull_request:
|
|
107
|
+
branches: [main]
|
|
99
108
|
|
|
100
109
|
jobs:
|
|
101
|
-
|
|
110
|
+
CI:
|
|
102
111
|
runs-on: ubuntu-latest
|
|
112
|
+
env:
|
|
113
|
+
CI: "true"
|
|
103
114
|
steps:
|
|
104
115
|
- uses: actions/checkout@v4
|
|
116
|
+
|
|
105
117
|
- uses: pnpm/action-setup@v4
|
|
118
|
+
# version is read from package.json#packageManager — do not duplicate here
|
|
119
|
+
|
|
106
120
|
- uses: actions/setup-node@v4
|
|
107
121
|
with:
|
|
108
|
-
node-version:
|
|
122
|
+
node-version: 24
|
|
109
123
|
cache: pnpm
|
|
110
|
-
|
|
111
|
-
-
|
|
112
|
-
|
|
124
|
+
|
|
125
|
+
- name: Install dependencies
|
|
126
|
+
run: pnpm install --frozen-lockfile
|
|
127
|
+
|
|
128
|
+
- name: Build plugins
|
|
129
|
+
run: pnpm exec aipm build
|
|
130
|
+
|
|
131
|
+
- name: Verify the tree is clean after build (freshness)
|
|
132
|
+
run: |
|
|
133
|
+
if [ -n "$(git status --porcelain)" ]; then
|
|
134
|
+
echo "::error::Working tree is dirty after 'aipm build'. Run 'aipm build' locally and commit the regenerated artifacts."
|
|
135
|
+
git status --porcelain
|
|
136
|
+
git --no-pager diff
|
|
137
|
+
exit 1
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
- name: Validate plugins
|
|
141
|
+
run: pnpm exec aipm validate
|
|
113
142
|
`;
|
|
114
143
|
}
|
|
115
144
|
/** `.gitignore` for a consumer repo: dependencies, build intermediates, OS/local cruft. */
|
|
@@ -121,22 +150,37 @@ function renderGitignore() {
|
|
|
121
150
|
`;
|
|
122
151
|
}
|
|
123
152
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
153
|
+
* Toolkit-owned **scaffold** files that `aipm init --refresh` keeps in sync with the installed
|
|
154
|
+
* tooling: the CI workflow and `.gitignore`. These are pure tooling recipes — their content is
|
|
155
|
+
* independent of the repo name and the pinned toolkit version, so refresh can re-render them with
|
|
156
|
+
* no inputs and compare byte-for-byte. (Files with repo identity or user content — `package.json`,
|
|
157
|
+
* `aipm.workspace.ts`, `README.md`, plugins, `aipm build` output — are deliberately NOT here.)
|
|
126
158
|
*
|
|
127
|
-
*
|
|
128
|
-
* registries, an empty `plugins/` (seeded with `.gitkeep` so the directory is tracked), and the
|
|
129
|
-
* CI workflow. Output is a pure function of the two inputs — stable ordering, no timestamps.
|
|
159
|
+
* Output is deterministic and stably ordered.
|
|
130
160
|
*/
|
|
131
|
-
export function
|
|
161
|
+
export function buildManagedScaffoldFiles() {
|
|
132
162
|
return [
|
|
133
|
-
{ path: 'package.json', content: renderPackageJson(name, toolkitVersion) },
|
|
134
163
|
{ path: '.gitignore', content: renderGitignore() },
|
|
164
|
+
{ path: '.github/workflows/ci.yml', content: renderCiWorkflow() },
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Build the complete, deterministic seed file set for a consumer repo named `name`, pinning the
|
|
169
|
+
* `cli`/`core` dev dependencies to carets of `cliVersion`/`coreVersion` respectively.
|
|
170
|
+
*
|
|
171
|
+
* The set mirrors §3.2: `package.json`, the {@link buildManagedScaffoldFiles managed scaffold
|
|
172
|
+
* files} (`.gitignore`, CI workflow), `README.md`, both repo-root marketplace registries, and an
|
|
173
|
+
* empty `plugins/` (seeded with `.gitkeep` so the directory is tracked). Output is a pure function
|
|
174
|
+
* of the inputs — stable ordering, no timestamps.
|
|
175
|
+
*/
|
|
176
|
+
export function buildInitFiles(name, cliVersion, coreVersion) {
|
|
177
|
+
return [
|
|
178
|
+
{ path: 'package.json', content: renderPackageJson(name, cliVersion, coreVersion) },
|
|
135
179
|
{ path: 'README.md', content: renderReadme(name) },
|
|
136
180
|
{ path: '.claude-plugin/marketplace.json', content: renderEmptyMarketplace() },
|
|
137
181
|
{ path: '.cursor-plugin/marketplace.json', content: renderEmptyMarketplace() },
|
|
138
182
|
{ path: 'plugins/.gitkeep', content: '' },
|
|
139
|
-
|
|
183
|
+
...buildManagedScaffoldFiles(),
|
|
140
184
|
];
|
|
141
185
|
}
|
|
142
186
|
//# sourceMappingURL=init-template.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-template.js","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;AACxB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;AACtB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"init-template.js","sourceRoot":"","sources":["../../src/pipeline/init-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;AACxB,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;AACtB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC;AAExB;;;;GAIG;AACH,MAAM,eAAe,GAAG,cAAc,CAAC;AAUvC;;;;;;;;;;;;;GAaG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,UAAkB,EAAE,WAAmB;IAC9E,MAAM,GAAG,GAAG;QACV,IAAI;QACJ,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,QAAQ;QACd,cAAc,EAAE,eAAe;QAC/B,OAAO,EAAE;YACP,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,eAAe;YACtB,QAAQ,EAAE,eAAe;SAC1B;QACD,eAAe,EAAE;YACf,4BAA4B,EAAE,IAAI,UAAU,EAAE;YAC9C,6BAA6B,EAAE,IAAI,WAAW,EAAE;SACjD;KACF,CAAC;IACF,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,+FAA+F;AAC/F,SAAS,sBAAsB;IAC7B,OAAO,IAAI,CAAA;;;CAGZ,CAAC;AACF,CAAC;AAED,2EAA2E;AAC3E,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,EAAE,CAAA,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;CAwBnB,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB;IACvB,OAAO,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCZ,CAAC;AACF,CAAC;AAED,2FAA2F;AAC3F,SAAS,eAAe;IACtB,OAAO;;;;CAIR,CAAC;AACF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;QAClD,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE;KAClE,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,UAAkB,EAAE,WAAmB;IAClF,OAAO;QACL,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE;QACnF,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE;QAClD,EAAE,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QAC9E,EAAE,IAAI,EAAE,iCAAiC,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;QAC9E,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,GAAG,yBAAyB,EAAE;KAC/B,CAAC;AACJ,CAAC"}
|
package/dist/pipeline/init.d.ts
CHANGED
|
@@ -4,35 +4,38 @@
|
|
|
4
4
|
*
|
|
5
5
|
* This is the filesystem-writing orchestrator behind the public `init` operation and the
|
|
6
6
|
* `aipm init [dir]` CLI surface. The generated file *contents* live in `init-template.ts`; this
|
|
7
|
-
* module is the I/O boundary: it resolves the
|
|
8
|
-
*
|
|
7
|
+
* module is the I/O boundary: it resolves the versions to pin, refuses to clobber a non-empty
|
|
8
|
+
* target, writes the seed tree, and seeds the `.aipm/scaffold.json` refresh sidecar.
|
|
9
9
|
*
|
|
10
|
-
* **Version pinning
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
13
|
-
*
|
|
14
|
-
* the
|
|
10
|
+
* **Version pinning.** `cli` and `core` ship independently and may differ (e.g. `cli 0.1.1` ships
|
|
11
|
+
* with `core 0.2.0`), so the generated `package.json` pins each to a caret of its *own* version.
|
|
12
|
+
* `core`'s version is read at runtime from this package's `package.json` (resolved relative to
|
|
13
|
+
* {@link import.meta.url}, exactly as `load-config.ts` resolves the package entrypoint); `cli`'s
|
|
14
|
+
* version is supplied by the cli entrypoint via {@link InitOptions.cliVersion} (it reads its own
|
|
15
|
+
* `package.json`). When `cliVersion` is omitted, it falls back to core's version.
|
|
15
16
|
*
|
|
16
17
|
* @see docs/specs/architecture.md §3.2 (template repo contents)
|
|
17
|
-
* @see docs/specs/architecture.md §9.1 (lockstep release lines)
|
|
18
18
|
* @see docs/specs/architecture.md §11 (template→toolkit dependency contract)
|
|
19
|
+
* @see docs/specs/scaffold-refresh-and-upgrade.md (`aipm init --refresh`)
|
|
19
20
|
*/
|
|
20
21
|
import type { InitOptions } from './types.js';
|
|
21
22
|
/**
|
|
22
23
|
* Scaffold a thin consumer repo at `targetDir` (§3.2).
|
|
23
24
|
*
|
|
24
|
-
* Writes `package.json` (with
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `aipm
|
|
28
|
-
* `
|
|
25
|
+
* Writes `package.json` (with `cli`/`core` dev dependencies pinned to carets of their respective
|
|
26
|
+
* versions), `.gitignore`, `README.md`, both repo-root marketplace registries (`{ "plugins": [] }`),
|
|
27
|
+
* an empty `plugins/` (tracked via `.gitkeep`), and a CI workflow that runs `aipm build` then
|
|
28
|
+
* `aipm validate` (§10.5 freshness). It also seeds `.aipm/scaffold.json` so a later
|
|
29
|
+
* `aipm init --refresh` can tell pristine toolkit-owned files from user edits. The repo name
|
|
30
|
+
* defaults to `basename(targetDir)`; override it with `opts.name`.
|
|
29
31
|
*
|
|
30
32
|
* **Refuses to clobber.** If `targetDir` exists and is a non-empty directory (or exists as a
|
|
31
33
|
* non-directory), the function throws and writes nothing. Creating into a fresh or empty directory
|
|
32
34
|
* is fine.
|
|
33
35
|
*
|
|
34
36
|
* @param targetDir - Absolute or relative path to the directory to scaffold into.
|
|
35
|
-
* @param opts - Init options; `name` overrides the derived repo name
|
|
37
|
+
* @param opts - Init options; `name` overrides the derived repo name, `cliVersion` the pinned cli
|
|
38
|
+
* dependency version (defaults to core's version).
|
|
36
39
|
* @throws {Error} When `targetDir` exists and is non-empty (or is not a directory).
|
|
37
40
|
*/
|
|
38
41
|
export declare function runInit(targetDir: string, opts?: InitOptions): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA6B9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BtF"}
|
package/dist/pipeline/init.js
CHANGED
|
@@ -4,23 +4,25 @@
|
|
|
4
4
|
*
|
|
5
5
|
* This is the filesystem-writing orchestrator behind the public `init` operation and the
|
|
6
6
|
* `aipm init [dir]` CLI surface. The generated file *contents* live in `init-template.ts`; this
|
|
7
|
-
* module is the I/O boundary: it resolves the
|
|
8
|
-
*
|
|
7
|
+
* module is the I/O boundary: it resolves the versions to pin, refuses to clobber a non-empty
|
|
8
|
+
* target, writes the seed tree, and seeds the `.aipm/scaffold.json` refresh sidecar.
|
|
9
9
|
*
|
|
10
|
-
* **Version pinning
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
13
|
-
*
|
|
14
|
-
* the
|
|
10
|
+
* **Version pinning.** `cli` and `core` ship independently and may differ (e.g. `cli 0.1.1` ships
|
|
11
|
+
* with `core 0.2.0`), so the generated `package.json` pins each to a caret of its *own* version.
|
|
12
|
+
* `core`'s version is read at runtime from this package's `package.json` (resolved relative to
|
|
13
|
+
* {@link import.meta.url}, exactly as `load-config.ts` resolves the package entrypoint); `cli`'s
|
|
14
|
+
* version is supplied by the cli entrypoint via {@link InitOptions.cliVersion} (it reads its own
|
|
15
|
+
* `package.json`). When `cliVersion` is omitted, it falls back to core's version.
|
|
15
16
|
*
|
|
16
17
|
* @see docs/specs/architecture.md §3.2 (template repo contents)
|
|
17
|
-
* @see docs/specs/architecture.md §9.1 (lockstep release lines)
|
|
18
18
|
* @see docs/specs/architecture.md §11 (template→toolkit dependency contract)
|
|
19
|
+
* @see docs/specs/scaffold-refresh-and-upgrade.md (`aipm init --refresh`)
|
|
19
20
|
*/
|
|
20
21
|
import * as fs from 'node:fs';
|
|
21
22
|
import * as path from 'node:path';
|
|
22
23
|
import { fileURLToPath } from 'node:url';
|
|
23
24
|
import { buildInitFiles } from './init-template.js';
|
|
25
|
+
import { writeScaffoldSidecar } from './scaffold-refresh.js';
|
|
24
26
|
/**
|
|
25
27
|
* Read this package's `package.json#version`, resolved relative to this module's location.
|
|
26
28
|
*
|
|
@@ -51,18 +53,20 @@ function isFreshTarget(dir) {
|
|
|
51
53
|
/**
|
|
52
54
|
* Scaffold a thin consumer repo at `targetDir` (§3.2).
|
|
53
55
|
*
|
|
54
|
-
* Writes `package.json` (with
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* `aipm
|
|
58
|
-
* `
|
|
56
|
+
* Writes `package.json` (with `cli`/`core` dev dependencies pinned to carets of their respective
|
|
57
|
+
* versions), `.gitignore`, `README.md`, both repo-root marketplace registries (`{ "plugins": [] }`),
|
|
58
|
+
* an empty `plugins/` (tracked via `.gitkeep`), and a CI workflow that runs `aipm build` then
|
|
59
|
+
* `aipm validate` (§10.5 freshness). It also seeds `.aipm/scaffold.json` so a later
|
|
60
|
+
* `aipm init --refresh` can tell pristine toolkit-owned files from user edits. The repo name
|
|
61
|
+
* defaults to `basename(targetDir)`; override it with `opts.name`.
|
|
59
62
|
*
|
|
60
63
|
* **Refuses to clobber.** If `targetDir` exists and is a non-empty directory (or exists as a
|
|
61
64
|
* non-directory), the function throws and writes nothing. Creating into a fresh or empty directory
|
|
62
65
|
* is fine.
|
|
63
66
|
*
|
|
64
67
|
* @param targetDir - Absolute or relative path to the directory to scaffold into.
|
|
65
|
-
* @param opts - Init options; `name` overrides the derived repo name
|
|
68
|
+
* @param opts - Init options; `name` overrides the derived repo name, `cliVersion` the pinned cli
|
|
69
|
+
* dependency version (defaults to core's version).
|
|
66
70
|
* @throws {Error} When `targetDir` exists and is non-empty (or is not a directory).
|
|
67
71
|
*/
|
|
68
72
|
export async function runInit(targetDir, opts = {}) {
|
|
@@ -72,13 +76,17 @@ export async function runInit(targetDir, opts = {}) {
|
|
|
72
76
|
'Choose a new path or an empty directory.');
|
|
73
77
|
}
|
|
74
78
|
const name = opts.name ?? path.basename(resolved);
|
|
75
|
-
const
|
|
79
|
+
const core = coreVersion();
|
|
80
|
+
const cli = opts.cliVersion ?? core;
|
|
81
|
+
const files = buildInitFiles(name, cli, core);
|
|
76
82
|
fs.mkdirSync(resolved, { recursive: true });
|
|
77
83
|
for (const file of files) {
|
|
78
84
|
const full = path.join(resolved, file.path);
|
|
79
85
|
fs.mkdirSync(path.dirname(full), { recursive: true });
|
|
80
86
|
fs.writeFileSync(full, file.content, 'utf-8');
|
|
81
87
|
}
|
|
88
|
+
// Seed the refresh sidecar so `aipm init --refresh` has a baseline of toolkit-owned content.
|
|
89
|
+
writeScaffoldSidecar(resolved);
|
|
82
90
|
return Promise.resolve();
|
|
83
91
|
}
|
|
84
92
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/pipeline/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D;;;;;;;GAOG;AACH,SAAS,WAAW;IAClB,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,sFAAsF;IACtF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAwB,CAAC;IACjF,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,OAAoB,EAAE;IACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,oDAAoD;YACxF,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;IACpC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAE9C,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,6FAA6F;IAC7F,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @see docs/specs/architecture.md §8.1
|
|
11
11
|
*/
|
|
12
|
-
import type { BuildOptions, BuildResult, InitOptions, MigrateOptions, MigrateResult, ScaffoldOptions, SupportReport, TargetId, ValidateOptions, ValidationResult } from './types.js';
|
|
12
|
+
import type { BuildOptions, BuildResult, InitOptions, MigrateOptions, MigrateResult, RefreshOptions, RefreshOutcome, ScaffoldOptions, SupportReport, TargetId, ValidateOptions, ValidationResult } from './types.js';
|
|
13
13
|
/**
|
|
14
14
|
* Build a single plugin or every plugin under a repo root. `path` may be a plugin directory
|
|
15
15
|
* (contains `aipm.config.ts`) or a repo root (contains `plugins/`); the orchestrator detects
|
|
@@ -34,6 +34,16 @@ export declare function validate(targetPath: string, opts?: ValidateOptions): Pr
|
|
|
34
34
|
* @public
|
|
35
35
|
*/
|
|
36
36
|
export declare function init(targetDir: string, opts?: InitOptions): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Refresh the toolkit-owned scaffold files (CI workflow, `.gitignore`) of an existing marketplace
|
|
39
|
+
* repo at `targetDir` to match the installed tooling — the upgrade path after
|
|
40
|
+
* `pnpm up @ai-plugin-marketplace/*`. Guarded by the `.aipm/scaffold.json` content-hash sidecar:
|
|
41
|
+
* user-modified files are reported as conflicts and left untouched unless `opts.force` is set.
|
|
42
|
+
* Returns one outcome per managed file; never rejects on conflict.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare function refreshScaffold(targetDir: string, opts?: RefreshOptions): Promise<RefreshOutcome[]>;
|
|
37
47
|
/**
|
|
38
48
|
* Scaffold a new plugin under the cwd's configured plugins root (`<cwd>/plugins/<name>` by
|
|
39
49
|
* default, or the relocated `pluginsRoot` from an `aipm.repo.ts`). The plugins directory is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,aAAa,EACb,QAAQ,EACR,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC,cAAc,EAAE,CAAC,CAK3B;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKtF;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAMrF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAEtE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,SAAS,QAAQ,EAAE,CAEjD"}
|
|
@@ -13,6 +13,7 @@ import * as path from 'node:path';
|
|
|
13
13
|
import { runBuild } from './build.js';
|
|
14
14
|
import { runInit } from './init.js';
|
|
15
15
|
import { loadRepoConfig } from './load-config.js';
|
|
16
|
+
import { runRefreshScaffold } from './scaffold-refresh.js';
|
|
16
17
|
import { runScaffold, runAddTarget, runCheckSupport } from './scaffold.js';
|
|
17
18
|
import { TARGET_IDS } from './types.js';
|
|
18
19
|
import { runValidate } from './validate.js';
|
|
@@ -50,6 +51,21 @@ export function validate(targetPath, opts) {
|
|
|
50
51
|
export function init(targetDir, opts) {
|
|
51
52
|
return runInit(targetDir, opts);
|
|
52
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Refresh the toolkit-owned scaffold files (CI workflow, `.gitignore`) of an existing marketplace
|
|
56
|
+
* repo at `targetDir` to match the installed tooling — the upgrade path after
|
|
57
|
+
* `pnpm up @ai-plugin-marketplace/*`. Guarded by the `.aipm/scaffold.json` content-hash sidecar:
|
|
58
|
+
* user-modified files are reported as conflicts and left untouched unless `opts.force` is set.
|
|
59
|
+
* Returns one outcome per managed file; never rejects on conflict.
|
|
60
|
+
*
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
export function refreshScaffold(targetDir, opts) {
|
|
64
|
+
// Defer into the microtask queue so a synchronous failure in the orchestrator (e.g. an I/O error)
|
|
65
|
+
// surfaces as a rejected promise — matching `refreshScaffold(...).catch(...)` expectations —
|
|
66
|
+
// rather than throwing from this call before the promise exists.
|
|
67
|
+
return Promise.resolve().then(() => runRefreshScaffold(targetDir, opts));
|
|
68
|
+
}
|
|
53
69
|
/**
|
|
54
70
|
* Scaffold a new plugin under the cwd's configured plugins root (`<cwd>/plugins/<name>` by
|
|
55
71
|
* default, or the relocated `pluginsRoot` from an `aipm.repo.ts`). The plugins directory is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/pipeline/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAgB5C,sGAAsG;AACtG,SAAS,IAAI;IACX,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,UAAkB,EAAE,IAAmB;IAC3D,OAAO,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,UAAkB,EAAE,IAAsB;IACjE,OAAO,WAAW,CAAC,UAAU,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAAC,SAAiB,EAAE,IAAkB;IACxD,OAAO,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,IAAqB;IAErB,kGAAkG;IAClG,6FAA6F;IAC7F,iEAAiE;IACjE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAwB,EAAE;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa,EAAE,KAAsB;IAC3D,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,MAAM,EAAE,sBAAsB;QAC9B,iBAAiB,EAAE,CAAC;QACpB,YAAY,EAAE,EAAE;KACjB,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,OAAO,eAAe,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAgB;IAC3D,OAAO,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aipm init --refresh` — keep a marketplace repo's **toolkit-owned scaffold files** (the CI
|
|
3
|
+
* workflow and `.gitignore`) in sync with the installed tooling, and serve as the upgrade path for
|
|
4
|
+
* any marketplace repo after `pnpm up @ai-plugin-marketplace/*`.
|
|
5
|
+
*
|
|
6
|
+
* Safety rests on a content-hash sidecar at `.aipm/scaffold.json` (mirroring the root-emission
|
|
7
|
+
* sidecar `.aipm/generated-root.json`): it records a hash of the exact content the toolkit last
|
|
8
|
+
* wrote each managed file. Refresh updates a file only when it is still pristine (matches the
|
|
9
|
+
* recorded hash) or missing; a file the user has edited surfaces as a reported conflict and is left
|
|
10
|
+
* untouched unless `--force` is given. A repo with no sidecar entry bootstraps: an already-in-sync
|
|
11
|
+
* file is adopted silently, a diverged one is a conflict to review.
|
|
12
|
+
*
|
|
13
|
+
* The managed set is deliberately narrow — only the pure tooling-recipe files (see
|
|
14
|
+
* {@link buildManagedScaffoldFiles}). `package.json` (deps are `pnpm up`'s job), `aipm.workspace.ts`
|
|
15
|
+
* (repo identity), `README.md` (authored), plugins, and `aipm build` output are never touched.
|
|
16
|
+
*
|
|
17
|
+
* @see docs/specs/scaffold-refresh-and-upgrade.md
|
|
18
|
+
*/
|
|
19
|
+
import type { RefreshOptions, RefreshOutcome } from './types.js';
|
|
20
|
+
/** A recorded `{ path, hash }` pair: the hash of the content the toolkit last wrote at `path`. */
|
|
21
|
+
interface SidecarEntry {
|
|
22
|
+
path: string;
|
|
23
|
+
hash: string;
|
|
24
|
+
}
|
|
25
|
+
/** Content hash recorded in the sidecar. `sha256-`-prefixed hex over the UTF-8 bytes. */
|
|
26
|
+
export declare function hashScaffoldContent(content: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Serialize a sidecar payload: `{ version, files }` with `files` sorted by path for determinism,
|
|
29
|
+
* 2-space JSON + trailing newline (matching the repo's other generated JSON).
|
|
30
|
+
*/
|
|
31
|
+
export declare function serializeScaffoldSidecar(entries: readonly SidecarEntry[]): string;
|
|
32
|
+
/** Inputs to the pure per-file refresh decision. */
|
|
33
|
+
export interface ManagedFileDecisionInput {
|
|
34
|
+
/** Canonical content the toolkit would render for this file. */
|
|
35
|
+
render: string;
|
|
36
|
+
/** Current on-disk content, or `null` when the file is missing. */
|
|
37
|
+
current: string | null;
|
|
38
|
+
/** Hash recorded in the sidecar for this file, or `null` when untracked. */
|
|
39
|
+
recordedHash: string | null;
|
|
40
|
+
/** Whether `--force` was given. */
|
|
41
|
+
force: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Result of the pure per-file refresh decision. */
|
|
44
|
+
export interface ManagedFileDecision {
|
|
45
|
+
status: RefreshOutcome['status'];
|
|
46
|
+
/** Whether to write `render` to disk. */
|
|
47
|
+
write: boolean;
|
|
48
|
+
/** Hash to record in the new sidecar, or `null` to preserve the prior entry (or stay untracked). */
|
|
49
|
+
recordHash: string | null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Decide what to do with one managed scaffold file. Pure — all filesystem state is passed in — so
|
|
53
|
+
* the decision table is unit-testable in isolation.
|
|
54
|
+
*
|
|
55
|
+
* | On-disk state | Result |
|
|
56
|
+
* |-------------------------------------------------|---------------|
|
|
57
|
+
* | missing | `recreated` |
|
|
58
|
+
* | matches the current render | `unchanged` |
|
|
59
|
+
* | differs from render, matches recorded hash | `updated` |
|
|
60
|
+
* | differs from render & recorded (or untracked) | `conflict` * |
|
|
61
|
+
* | …same, with `force` | `overwritten` |
|
|
62
|
+
*
|
|
63
|
+
* \* `unchanged` also adopts an untracked-but-in-sync file by recording its hash.
|
|
64
|
+
*/
|
|
65
|
+
export declare function decideManagedFile(input: ManagedFileDecisionInput): ManagedFileDecision;
|
|
66
|
+
/**
|
|
67
|
+
* Seed `.aipm/scaffold.json` for a freshly scaffolded repo, recording the hash of every managed
|
|
68
|
+
* scaffold file as just written by `aipm init`. Called by {@link runInit} after the seed tree is
|
|
69
|
+
* written so the first `--refresh` has a baseline.
|
|
70
|
+
*/
|
|
71
|
+
export declare function writeScaffoldSidecar(repoRoot: string): void;
|
|
72
|
+
/**
|
|
73
|
+
* Refresh the toolkit-owned scaffold files of an existing repo at `repoRoot`, re-rendering each
|
|
74
|
+
* from the installed tooling and updating it in place when safe (see {@link decideManagedFile}).
|
|
75
|
+
* Writes the updated `.aipm/scaffold.json` sidecar and returns one {@link RefreshOutcome} per
|
|
76
|
+
* managed file. Never throws on conflict — conflicts are reported, not failures.
|
|
77
|
+
*/
|
|
78
|
+
export declare function runRefreshScaffold(repoRoot: string, opts?: RefreshOptions): RefreshOutcome[];
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=scaffold-refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-refresh.d.ts","sourceRoot":"","sources":["../../src/pipeline/scaffold-refresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjE,kGAAkG;AAClG,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAOD,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAGjF;AA+BD,oDAAoD;AACpD,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mCAAmC;IACnC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,yCAAyC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,oGAAoG;IACpG,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,wBAAwB,GAAG,mBAAmB,CAmBtF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQ3D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,cAAc,EAAE,CAmChG"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `aipm init --refresh` — keep a marketplace repo's **toolkit-owned scaffold files** (the CI
|
|
3
|
+
* workflow and `.gitignore`) in sync with the installed tooling, and serve as the upgrade path for
|
|
4
|
+
* any marketplace repo after `pnpm up @ai-plugin-marketplace/*`.
|
|
5
|
+
*
|
|
6
|
+
* Safety rests on a content-hash sidecar at `.aipm/scaffold.json` (mirroring the root-emission
|
|
7
|
+
* sidecar `.aipm/generated-root.json`): it records a hash of the exact content the toolkit last
|
|
8
|
+
* wrote each managed file. Refresh updates a file only when it is still pristine (matches the
|
|
9
|
+
* recorded hash) or missing; a file the user has edited surfaces as a reported conflict and is left
|
|
10
|
+
* untouched unless `--force` is given. A repo with no sidecar entry bootstraps: an already-in-sync
|
|
11
|
+
* file is adopted silently, a diverged one is a conflict to review.
|
|
12
|
+
*
|
|
13
|
+
* The managed set is deliberately narrow — only the pure tooling-recipe files (see
|
|
14
|
+
* {@link buildManagedScaffoldFiles}). `package.json` (deps are `pnpm up`'s job), `aipm.workspace.ts`
|
|
15
|
+
* (repo identity), `README.md` (authored), plugins, and `aipm build` output are never touched.
|
|
16
|
+
*
|
|
17
|
+
* @see docs/specs/scaffold-refresh-and-upgrade.md
|
|
18
|
+
*/
|
|
19
|
+
import { createHash } from 'node:crypto';
|
|
20
|
+
import * as fs from 'node:fs';
|
|
21
|
+
import * as path from 'node:path';
|
|
22
|
+
import { buildManagedScaffoldFiles } from './init-template.js';
|
|
23
|
+
/** Sidecar location relative to the repo root. */
|
|
24
|
+
const SIDECAR_REL = ['.aipm', 'scaffold.json'];
|
|
25
|
+
/** Schema version of the sidecar payload. */
|
|
26
|
+
const SIDECAR_VERSION = 1;
|
|
27
|
+
/** Absolute path of the scaffold sidecar under `repoRoot`. */
|
|
28
|
+
function sidecarPath(repoRoot) {
|
|
29
|
+
return path.join(repoRoot, ...SIDECAR_REL);
|
|
30
|
+
}
|
|
31
|
+
/** Content hash recorded in the sidecar. `sha256-`-prefixed hex over the UTF-8 bytes. */
|
|
32
|
+
export function hashScaffoldContent(content) {
|
|
33
|
+
return `sha256-${createHash('sha256').update(content, 'utf-8').digest('hex')}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Serialize a sidecar payload: `{ version, files }` with `files` sorted by path for determinism,
|
|
37
|
+
* 2-space JSON + trailing newline (matching the repo's other generated JSON).
|
|
38
|
+
*/
|
|
39
|
+
export function serializeScaffoldSidecar(entries) {
|
|
40
|
+
const files = [...entries].sort((a, b) => a.path.localeCompare(b.path));
|
|
41
|
+
return `${JSON.stringify({ version: SIDECAR_VERSION, files }, null, 2)}\n`;
|
|
42
|
+
}
|
|
43
|
+
/** Read the prior sidecar into a `path → hash` map. Missing or malformed sidecar → empty map. */
|
|
44
|
+
function readSidecar(repoRoot) {
|
|
45
|
+
const map = new Map();
|
|
46
|
+
const abs = sidecarPath(repoRoot);
|
|
47
|
+
if (!fs.existsSync(abs))
|
|
48
|
+
return map;
|
|
49
|
+
// Read errors (permissions, transient I/O) propagate — they are real operational problems, not a
|
|
50
|
+
// "malformed sidecar" we should silently swallow. Only a JSON parse failure is tolerated.
|
|
51
|
+
const raw = fs.readFileSync(abs, 'utf-8');
|
|
52
|
+
let parsed;
|
|
53
|
+
try {
|
|
54
|
+
parsed = JSON.parse(raw);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// A malformed sidecar is treated as absent: every managed file becomes "untracked" and must
|
|
58
|
+
// either already match the current render (adopted) or be resolved via --force.
|
|
59
|
+
return map;
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(parsed.files)) {
|
|
62
|
+
for (const rawEntry of parsed.files) {
|
|
63
|
+
const entry = rawEntry;
|
|
64
|
+
if (typeof entry.path === 'string' && typeof entry.hash === 'string') {
|
|
65
|
+
map.set(entry.path, entry.hash);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return map;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Decide what to do with one managed scaffold file. Pure — all filesystem state is passed in — so
|
|
73
|
+
* the decision table is unit-testable in isolation.
|
|
74
|
+
*
|
|
75
|
+
* | On-disk state | Result |
|
|
76
|
+
* |-------------------------------------------------|---------------|
|
|
77
|
+
* | missing | `recreated` |
|
|
78
|
+
* | matches the current render | `unchanged` |
|
|
79
|
+
* | differs from render, matches recorded hash | `updated` |
|
|
80
|
+
* | differs from render & recorded (or untracked) | `conflict` * |
|
|
81
|
+
* | …same, with `force` | `overwritten` |
|
|
82
|
+
*
|
|
83
|
+
* \* `unchanged` also adopts an untracked-but-in-sync file by recording its hash.
|
|
84
|
+
*/
|
|
85
|
+
export function decideManagedFile(input) {
|
|
86
|
+
const { render, current, recordedHash, force } = input;
|
|
87
|
+
const renderHash = hashScaffoldContent(render);
|
|
88
|
+
if (current === null)
|
|
89
|
+
return { status: 'recreated', write: true, recordHash: renderHash };
|
|
90
|
+
const currentHash = hashScaffoldContent(current);
|
|
91
|
+
if (currentHash === renderHash)
|
|
92
|
+
return { status: 'unchanged', write: false, recordHash: renderHash };
|
|
93
|
+
// Content differs from the current render.
|
|
94
|
+
if (recordedHash !== null && currentHash === recordedHash) {
|
|
95
|
+
// Pristine: the file is exactly what the toolkit last wrote, so it is safe to upgrade.
|
|
96
|
+
return { status: 'updated', write: true, recordHash: renderHash };
|
|
97
|
+
}
|
|
98
|
+
// Diverged from the recorded hash (user-edited) or untracked and not in sync.
|
|
99
|
+
if (force)
|
|
100
|
+
return { status: 'overwritten', write: true, recordHash: renderHash };
|
|
101
|
+
return { status: 'conflict', write: false, recordHash: null };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Seed `.aipm/scaffold.json` for a freshly scaffolded repo, recording the hash of every managed
|
|
105
|
+
* scaffold file as just written by `aipm init`. Called by {@link runInit} after the seed tree is
|
|
106
|
+
* written so the first `--refresh` has a baseline.
|
|
107
|
+
*/
|
|
108
|
+
export function writeScaffoldSidecar(repoRoot) {
|
|
109
|
+
const entries = buildManagedScaffoldFiles().map((file) => ({
|
|
110
|
+
path: file.path,
|
|
111
|
+
hash: hashScaffoldContent(file.content),
|
|
112
|
+
}));
|
|
113
|
+
const abs = sidecarPath(repoRoot);
|
|
114
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
115
|
+
fs.writeFileSync(abs, serializeScaffoldSidecar(entries), 'utf-8');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Refresh the toolkit-owned scaffold files of an existing repo at `repoRoot`, re-rendering each
|
|
119
|
+
* from the installed tooling and updating it in place when safe (see {@link decideManagedFile}).
|
|
120
|
+
* Writes the updated `.aipm/scaffold.json` sidecar and returns one {@link RefreshOutcome} per
|
|
121
|
+
* managed file. Never throws on conflict — conflicts are reported, not failures.
|
|
122
|
+
*/
|
|
123
|
+
export function runRefreshScaffold(repoRoot, opts = {}) {
|
|
124
|
+
const force = opts.force ?? false;
|
|
125
|
+
const resolved = path.resolve(repoRoot);
|
|
126
|
+
const recorded = readSidecar(resolved);
|
|
127
|
+
const outcomes = [];
|
|
128
|
+
const newEntries = [];
|
|
129
|
+
for (const file of buildManagedScaffoldFiles()) {
|
|
130
|
+
const abs = path.join(resolved, file.path);
|
|
131
|
+
const current = fs.existsSync(abs) ? fs.readFileSync(abs, 'utf-8') : null;
|
|
132
|
+
const recordedHash = recorded.get(file.path) ?? null;
|
|
133
|
+
const decision = decideManagedFile({ render: file.content, current, recordedHash, force });
|
|
134
|
+
if (decision.write) {
|
|
135
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
136
|
+
fs.writeFileSync(abs, file.content, 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
if (decision.recordHash !== null) {
|
|
139
|
+
newEntries.push({ path: file.path, hash: decision.recordHash });
|
|
140
|
+
}
|
|
141
|
+
else if (recordedHash !== null) {
|
|
142
|
+
// Conflict left untouched: preserve the prior recorded hash so it stays tracked.
|
|
143
|
+
newEntries.push({ path: file.path, hash: recordedHash });
|
|
144
|
+
}
|
|
145
|
+
outcomes.push({ path: file.path, status: decision.status });
|
|
146
|
+
}
|
|
147
|
+
const sidecarAbs = sidecarPath(resolved);
|
|
148
|
+
fs.mkdirSync(path.dirname(sidecarAbs), { recursive: true });
|
|
149
|
+
fs.writeFileSync(sidecarAbs, serializeScaffoldSidecar(newEntries), 'utf-8');
|
|
150
|
+
return outcomes;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=scaffold-refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-refresh.js","sourceRoot":"","sources":["../../src/pipeline/scaffold-refresh.ts"],"names":[],"mappings":"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"}
|
package/dist/pipeline/types.d.ts
CHANGED
|
@@ -139,6 +139,44 @@ export interface InitOptions {
|
|
|
139
139
|
* directory.
|
|
140
140
|
*/
|
|
141
141
|
name?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Version of `@ai-plugin-marketplace/cli` to pin the generated `package.json`'s `cli`
|
|
144
|
+
* dev dependency to (as `^<cliVersion>`). The cli entrypoint supplies its own version here; cli
|
|
145
|
+
* and core ship independently and may differ (e.g. `cli 0.1.1` ships with `core 0.2.0`). When
|
|
146
|
+
* omitted, falls back to core's own version (the historical lockstep assumption).
|
|
147
|
+
*/
|
|
148
|
+
cliVersion?: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Options for {@link refreshScaffold}.
|
|
152
|
+
*
|
|
153
|
+
* @public
|
|
154
|
+
*/
|
|
155
|
+
export interface RefreshOptions {
|
|
156
|
+
/**
|
|
157
|
+
* Overwrite toolkit-owned scaffold files even when their on-disk content has diverged from what
|
|
158
|
+
* the toolkit last wrote (i.e. the user edited them). Without this, diverged files are reported
|
|
159
|
+
* as conflicts and left untouched.
|
|
160
|
+
*/
|
|
161
|
+
force?: boolean;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Per-file outcome of a {@link refreshScaffold} run. Returned (one per managed scaffold file) so
|
|
165
|
+
* the CLI can report what changed without re-deriving it.
|
|
166
|
+
*
|
|
167
|
+
* @public
|
|
168
|
+
*/
|
|
169
|
+
export interface RefreshOutcome {
|
|
170
|
+
/** Repo-relative POSIX path of the managed scaffold file. */
|
|
171
|
+
path: string;
|
|
172
|
+
/**
|
|
173
|
+
* - `updated` — content changed and was rewritten (file was pristine or `--force`).
|
|
174
|
+
* - `unchanged` — already matched the current render; nothing written.
|
|
175
|
+
* - `recreated` — file was missing and was written from the render.
|
|
176
|
+
* - `conflict` — on-disk content diverged from the recorded hash; left untouched (no `--force`).
|
|
177
|
+
* - `overwritten` — diverged but rewritten because `--force` was set.
|
|
178
|
+
*/
|
|
179
|
+
status: 'updated' | 'unchanged' | 'recreated' | 'conflict' | 'overwritten';
|
|
142
180
|
}
|
|
143
181
|
/**
|
|
144
182
|
* Options for {@link migrate}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,oEAOiB,CAAC;AAmBzC;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,MAAM,EAAE,QAAQ,CAAC;CAClB;AAKD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,8EAA8E;IAC9E,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GACnB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,gBAAgB,GAChB,kBAAkB,GAClB,cAAc,GACd,0BAA0B,GAC1B,WAAW,GACX,sBAAsB,GACtB,yBAAyB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAKD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC9B,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-plugin-marketplace/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Core build pipeline, validation, and scaffolding for the AI plugin marketplace toolkit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Mike North <michael.l.north@gmail.com>",
|