prd-to-flutter 0.1.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 +149 -0
- package/bin/p2f.mjs +18 -0
- package/dist/cli.js +203 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/clean.js +35 -0
- package/dist/commands/clean.js.map +1 -0
- package/dist/commands/doctor.js +148 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/generate.js +120 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.js +46 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/paths.js +58 -0
- package/dist/commands/paths.js.map +1 -0
- package/dist/commands/remove.js +23 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/screenshots-audit.js +39 -0
- package/dist/commands/screenshots-audit.js.map +1 -0
- package/dist/commands/skills-install.js +21 -0
- package/dist/commands/skills-install.js.map +1 -0
- package/dist/commands/sync.js +84 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/update.js +93 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/core/existing-page-detector.js +463 -0
- package/dist/core/existing-page-detector.js.map +1 -0
- package/dist/core/fail-fast.js +50 -0
- package/dist/core/fail-fast.js.map +1 -0
- package/dist/core/feature-coverage-builder.js +667 -0
- package/dist/core/feature-coverage-builder.js.map +1 -0
- package/dist/core/flutter-project-scanner.js +393 -0
- package/dist/core/flutter-project-scanner.js.map +1 -0
- package/dist/core/implementation-plan-writer.js +190 -0
- package/dist/core/implementation-plan-writer.js.map +1 -0
- package/dist/core/logger.js +39 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/package-info.js +33 -0
- package/dist/core/package-info.js.map +1 -0
- package/dist/core/paths.js +37 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/playwright-capture.js +539 -0
- package/dist/core/playwright-capture.js.map +1 -0
- package/dist/core/playwright-cli.js +26 -0
- package/dist/core/playwright-cli.js.map +1 -0
- package/dist/core/playwright-install.js +40 -0
- package/dist/core/playwright-install.js.map +1 -0
- package/dist/core/prd-clone.js +131 -0
- package/dist/core/prd-clone.js.map +1 -0
- package/dist/core/prd-install.js +108 -0
- package/dist/core/prd-install.js.map +1 -0
- package/dist/core/profile.js +149 -0
- package/dist/core/profile.js.map +1 -0
- package/dist/core/project-doc-reader.js +252 -0
- package/dist/core/project-doc-reader.js.map +1 -0
- package/dist/core/report-writer.js +90 -0
- package/dist/core/report-writer.js.map +1 -0
- package/dist/core/route-name.js +60 -0
- package/dist/core/route-name.js.map +1 -0
- package/dist/core/run-context.js +160 -0
- package/dist/core/run-context.js.map +1 -0
- package/dist/core/screenshot-auditor.js +405 -0
- package/dist/core/screenshot-auditor.js.map +1 -0
- package/dist/core/screenshot-exploration-plan-writer.js +200 -0
- package/dist/core/screenshot-exploration-plan-writer.js.map +1 -0
- package/dist/core/semantic-model-builder.js +922 -0
- package/dist/core/semantic-model-builder.js.map +1 -0
- package/dist/core/skill-install.js +78 -0
- package/dist/core/skill-install.js.map +1 -0
- package/dist/core/stage-stub.js +24 -0
- package/dist/core/stage-stub.js.map +1 -0
- package/dist/core/task-index-writer.js +149 -0
- package/dist/core/task-index-writer.js.map +1 -0
- package/dist/core/update-checker.js +155 -0
- package/dist/core/update-checker.js.map +1 -0
- package/dist/core/vue-page-locator.js +748 -0
- package/dist/core/vue-page-locator.js.map +1 -0
- package/dist/core/vue-project-reader.js +116 -0
- package/dist/core/vue-project-reader.js.map +1 -0
- package/docs/artifacts-and-agent.md +203 -0
- package/docs/development.md +118 -0
- package/docs/usage.md +246 -0
- package/package.json +50 -0
- package/skills/p2f/SKILL.md +303 -0
- package/skills/p2f/references/page-layout-patterns.md +120 -0
- package/skills/p2f/references/youfi-flutter-guidelines.md +71 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { logger } from '../core/logger.js';
|
|
2
|
+
import { FailFastError, reportFailure } from '../core/fail-fast.js';
|
|
3
|
+
import { createRunContext, } from '../core/run-context.js';
|
|
4
|
+
import { prdClone } from '../core/prd-clone.js';
|
|
5
|
+
import { readFlutterProjectDocs } from '../core/project-doc-reader.js';
|
|
6
|
+
import { readVueProjectDocs } from '../core/vue-project-reader.js';
|
|
7
|
+
import { locateVuePage } from '../core/vue-page-locator.js';
|
|
8
|
+
import { capturePrototypeRuntime } from '../core/playwright-capture.js';
|
|
9
|
+
import { buildSemanticModel } from '../core/semantic-model-builder.js';
|
|
10
|
+
import { buildFeatureCoverage, mergeFeatureCoverageIntoSemanticModel, } from '../core/feature-coverage-builder.js';
|
|
11
|
+
import { writeScreenshotExplorationPlan } from '../core/screenshot-exploration-plan-writer.js';
|
|
12
|
+
import { scanFlutterProject } from '../core/flutter-project-scanner.js';
|
|
13
|
+
import { detectExistingFlutterPage } from '../core/existing-page-detector.js';
|
|
14
|
+
import { writeImplementationPlan } from '../core/implementation-plan-writer.js';
|
|
15
|
+
import { writeReport } from '../core/report-writer.js';
|
|
16
|
+
import { writeTaskIndex } from '../core/task-index-writer.js';
|
|
17
|
+
import { loadProjectProfile, ProfileConfigError } from '../core/profile.js';
|
|
18
|
+
export async function generateCommand(options) {
|
|
19
|
+
const ctx = createRunContext(options);
|
|
20
|
+
logger.stage(`p2f generate · ${options.pageName}`);
|
|
21
|
+
logger.info(`prototypeUrl: ${options.prototypeUrl}`);
|
|
22
|
+
logger.info(`workspace : ${ctx.paths.root}`);
|
|
23
|
+
logger.info(`taskDir : ${ctx.taskDir}`);
|
|
24
|
+
logger.info(`runDir : ${ctx.runDir}`);
|
|
25
|
+
try {
|
|
26
|
+
const { profile, configPath } = loadProjectProfile(ctx.paths.root);
|
|
27
|
+
logger.info(`profile : ${profile.name}${configPath ? ` (${configPath})` : ' (builtin)'}`);
|
|
28
|
+
// --- Phase 2 stages implemented now --------------------------------
|
|
29
|
+
logger.stage('Stage: sync-prd-source');
|
|
30
|
+
const sync = await prdClone(ctx);
|
|
31
|
+
logger.stage('Stage: read-flutter-docs');
|
|
32
|
+
readFlutterProjectDocs(ctx, profile, configPath);
|
|
33
|
+
const snapshot = scanFlutterProject(ctx, profile, configPath);
|
|
34
|
+
logger.stage('Stage: read-vue-docs');
|
|
35
|
+
const vueDocs = readVueProjectDocs(ctx, sync.path, profile);
|
|
36
|
+
// --- Phase 3+ stages still stubbed ---------------------------------
|
|
37
|
+
logger.stage('Stage: locate-vue-page');
|
|
38
|
+
const page = locateVuePage(ctx, vueDocs, options.prototypeUrl, profile);
|
|
39
|
+
writeTaskIndex(ctx, {
|
|
40
|
+
located: page,
|
|
41
|
+
vueDocs,
|
|
42
|
+
stage: 'located',
|
|
43
|
+
});
|
|
44
|
+
logger.stage('Stage: build-feature-coverage');
|
|
45
|
+
const coverage = buildFeatureCoverage(ctx, page, vueDocs);
|
|
46
|
+
logger.stage('Stage: capture-runtime');
|
|
47
|
+
const capture = await capturePrototypeRuntime(ctx, options.prototypeUrl, page);
|
|
48
|
+
logger.stage('Stage: build-semantic-model');
|
|
49
|
+
const model = buildSemanticModel(ctx, page, capture);
|
|
50
|
+
logger.stage('Stage: merge-feature-coverage');
|
|
51
|
+
mergeFeatureCoverageIntoSemanticModel(ctx, model, coverage);
|
|
52
|
+
logger.stage('Stage: write-screenshot-exploration-plan');
|
|
53
|
+
const screenshotPlan = writeScreenshotExplorationPlan(ctx, model, coverage, capture);
|
|
54
|
+
logger.stage('Stage: detect-existing-page');
|
|
55
|
+
const verdict = detectExistingFlutterPage(ctx, snapshot, model);
|
|
56
|
+
writeTaskIndex(ctx, {
|
|
57
|
+
located: page,
|
|
58
|
+
vueDocs,
|
|
59
|
+
snapshot,
|
|
60
|
+
verdict,
|
|
61
|
+
model,
|
|
62
|
+
stage: 'planned',
|
|
63
|
+
});
|
|
64
|
+
logger.stage('Stage: write-implementation-plan');
|
|
65
|
+
const plan = writeImplementationPlan(ctx, model, verdict, snapshot);
|
|
66
|
+
const report = writeReport(ctx, {
|
|
67
|
+
status: 'ready',
|
|
68
|
+
flutter: {
|
|
69
|
+
pageExisted: verdict.pageExists,
|
|
70
|
+
pageStatus: verdict.status,
|
|
71
|
+
confidence: verdict.confidence,
|
|
72
|
+
reviewRequired: verdict.agentReview.required,
|
|
73
|
+
targetModule: verdict.targetModule,
|
|
74
|
+
targetPageFile: verdict.targetPageFile ?? undefined,
|
|
75
|
+
},
|
|
76
|
+
risks: plan.highRisk,
|
|
77
|
+
reviewHints: plan.unknowns,
|
|
78
|
+
});
|
|
79
|
+
writeTaskIndex(ctx, {
|
|
80
|
+
located: page,
|
|
81
|
+
vueDocs,
|
|
82
|
+
snapshot,
|
|
83
|
+
verdict,
|
|
84
|
+
model,
|
|
85
|
+
stage: 'planned',
|
|
86
|
+
});
|
|
87
|
+
logger.success(`数据采集完成 · 报告:${report.pageMarkdown}`);
|
|
88
|
+
logger.info(`下一步:让 agent 读取 ${ctx.taskDir}/main.md,先按 ${screenshotPlan.markdownPath} 自动探索补全截图,再实现页面。`);
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
if (err instanceof ProfileConfigError) {
|
|
93
|
+
logger.error(err.message);
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
if (err instanceof FailFastError) {
|
|
97
|
+
reportFailure(err);
|
|
98
|
+
try {
|
|
99
|
+
writeReport(ctx, {
|
|
100
|
+
status: 'stopped',
|
|
101
|
+
failure: {
|
|
102
|
+
stage: err.detail.stage,
|
|
103
|
+
action: err.detail.action,
|
|
104
|
+
reason: err.detail.reason,
|
|
105
|
+
completedSteps: err.detail.completedSteps,
|
|
106
|
+
pendingSteps: err.detail.pendingSteps,
|
|
107
|
+
suggestions: err.detail.suggestions,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (reportErr) {
|
|
112
|
+
logger.warn(`报告写入失败(忽略):${reportErr.message}`);
|
|
113
|
+
}
|
|
114
|
+
return 1;
|
|
115
|
+
}
|
|
116
|
+
logger.error(`意外错误:${err.stack ?? String(err)}`);
|
|
117
|
+
return 1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { mkdirSync } from 'node:fs';
|
|
2
|
+
import { logger } from '../core/logger.js';
|
|
3
|
+
import { FailFastError, reportFailure } from '../core/fail-fast.js';
|
|
4
|
+
import { createRunContext, markComplete } from '../core/run-context.js';
|
|
5
|
+
import { skillInstall } from '../core/skill-install.js';
|
|
6
|
+
import { prdClone } from '../core/prd-clone.js';
|
|
7
|
+
import { prdInstall } from '../core/prd-install.js';
|
|
8
|
+
import { playwrightInstall } from '../core/playwright-install.js';
|
|
9
|
+
export async function initCommand(opts) {
|
|
10
|
+
// init does not have a target page; we reuse RunContext with a synthetic one.
|
|
11
|
+
const runOpts = {
|
|
12
|
+
pageName: '__bootstrap__',
|
|
13
|
+
prototypeUrl: '(bootstrap)',
|
|
14
|
+
workspace: opts.workspace,
|
|
15
|
+
kind: 'system',
|
|
16
|
+
stagePlan: ['sync-prd-source', 'prd-install', 'playwright-install', 'skill-install'],
|
|
17
|
+
};
|
|
18
|
+
const ctx = createRunContext(runOpts);
|
|
19
|
+
mkdirSync(ctx.paths.workspaceDir, { recursive: true });
|
|
20
|
+
mkdirSync(ctx.paths.pagesDir, { recursive: true });
|
|
21
|
+
mkdirSync(ctx.paths.projectDir, { recursive: true });
|
|
22
|
+
mkdirSync(ctx.paths.logsDir, { recursive: true });
|
|
23
|
+
try {
|
|
24
|
+
logger.stage('Stage: sync-prd-source');
|
|
25
|
+
const clone = await prdClone(ctx);
|
|
26
|
+
logger.stage('Stage: prd-install');
|
|
27
|
+
const deps = await prdInstall(ctx, clone.path);
|
|
28
|
+
logger.stage('Stage: playwright-install');
|
|
29
|
+
await playwrightInstall(ctx);
|
|
30
|
+
logger.stage(`Stage: skill-install · target ${ctx.paths.root}`);
|
|
31
|
+
const skill = skillInstall({ workspace: ctx.paths.root });
|
|
32
|
+
markComplete(ctx, 'skill-install');
|
|
33
|
+
logger.success(`init OK. prototype commit=${clone.commit.slice(0, 7)} source=${clone.source} ` +
|
|
34
|
+
`deps=${deps.packageManager}${deps.ran ? '(installed)' : '(cached)'} ` +
|
|
35
|
+
`chromium=ready skill=${skill.installed.length}/2`);
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (err instanceof FailFastError) {
|
|
40
|
+
reportFailure(err);
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAwB,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAMlE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAiB;IACjD,8EAA8E;IAC9E,MAAM,OAAO,GAAoB;QAC/B,QAAQ,EAAE,eAAe;QACzB,YAAY,EAAE,aAAa;QAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,CAAC,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,eAAe,CAAC;KACrF,CAAC;IACF,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACtC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QAElC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC1C,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAE7B,MAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,YAAY,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAEnC,MAAM,CAAC,OAAO,CACZ,6BAA6B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,KAAK,CAAC,MAAM,GAAG;YAC7E,QAAQ,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,GAAG;YACtE,wBAAwB,KAAK,CAAC,SAAS,CAAC,MAAM,IAAI,CACrD,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,aAAa,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { logger } from '../core/logger.js';
|
|
3
|
+
import { buildWorkspacePaths } from '../core/paths.js';
|
|
4
|
+
import { deriveTaskName } from '../core/route-name.js';
|
|
5
|
+
export async function pathsCommand(opts) {
|
|
6
|
+
if (!opts.json)
|
|
7
|
+
logger.stage('Stage: resolve-paths');
|
|
8
|
+
const paths = buildWorkspacePaths(opts.workspace);
|
|
9
|
+
const taskName = opts.pageName || opts.prototypeUrl
|
|
10
|
+
? deriveTaskName({ pageName: opts.pageName, prototypeUrl: opts.prototypeUrl })
|
|
11
|
+
: undefined;
|
|
12
|
+
const payload = {
|
|
13
|
+
workspaceRoot: paths.root,
|
|
14
|
+
p2fWorkspace: paths.workspaceDir,
|
|
15
|
+
prdSource: paths.prdSourceDir,
|
|
16
|
+
pages: paths.pagesDir,
|
|
17
|
+
project: paths.projectDir,
|
|
18
|
+
flutterProjectJson: join(paths.projectDir, 'flutter-project.json'),
|
|
19
|
+
logs: paths.logsDir,
|
|
20
|
+
...(taskName
|
|
21
|
+
? {
|
|
22
|
+
taskName,
|
|
23
|
+
taskDir: join(paths.pagesDir, taskName),
|
|
24
|
+
cliDir: join(paths.pagesDir, taskName, 'cli'),
|
|
25
|
+
agentDir: join(paths.pagesDir, taskName, 'agent'),
|
|
26
|
+
cliRuntimeDir: join(paths.pagesDir, taskName, 'cli', 'runtime'),
|
|
27
|
+
agentRuntimeDir: join(paths.pagesDir, taskName, 'agent', 'runtime'),
|
|
28
|
+
screenshotsDir: join(paths.pagesDir, taskName, 'agent', 'screenshots'),
|
|
29
|
+
agentManifest: join(paths.pagesDir, taskName, 'agent', 'manifest.json'),
|
|
30
|
+
mainMd: join(paths.pagesDir, taskName, 'main.md'),
|
|
31
|
+
}
|
|
32
|
+
: {}),
|
|
33
|
+
};
|
|
34
|
+
if (opts.json) {
|
|
35
|
+
process.stdout.write(JSON.stringify(payload, null, 2) + '\n');
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
logger.info(`workspaceRoot : ${payload.workspaceRoot}`);
|
|
39
|
+
logger.info(`p2fWorkspace : ${payload.p2fWorkspace}`);
|
|
40
|
+
logger.info(`prdSource : ${payload.prdSource}`);
|
|
41
|
+
logger.info(`pages : ${payload.pages}`);
|
|
42
|
+
logger.info(`project : ${payload.project}`);
|
|
43
|
+
logger.info(`flutterProject: ${payload.flutterProjectJson}`);
|
|
44
|
+
logger.info(`logs : ${payload.logs}`);
|
|
45
|
+
if (taskName) {
|
|
46
|
+
logger.info(`taskName : ${payload.taskName}`);
|
|
47
|
+
logger.info(`taskDir : ${payload.taskDir}`);
|
|
48
|
+
logger.info(`cliDir : ${payload.cliDir}`);
|
|
49
|
+
logger.info(`agentDir : ${payload.agentDir}`);
|
|
50
|
+
logger.info(`cliRuntimeDir : ${payload.cliRuntimeDir}`);
|
|
51
|
+
logger.info(`agentRuntime : ${payload.agentRuntimeDir}`);
|
|
52
|
+
logger.info(`screenshotsDir: ${payload.screenshotsDir}`);
|
|
53
|
+
logger.info(`agentManifest : ${payload.agentManifest}`);
|
|
54
|
+
logger.info(`mainMd : ${payload.mainMd}`);
|
|
55
|
+
}
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/commands/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { existsSync, rmSync } from 'node:fs';
|
|
2
|
+
import { logger } from '../core/logger.js';
|
|
3
|
+
import { buildWorkspacePaths } from '../core/paths.js';
|
|
4
|
+
import { listSkillTargets } from '../core/skill-install.js';
|
|
5
|
+
export async function removeCommand(opts) {
|
|
6
|
+
logger.stage('Stage: remove');
|
|
7
|
+
const paths = buildWorkspacePaths(opts.workspace);
|
|
8
|
+
const targets = [paths.workspaceDir, ...listSkillTargets(paths.root)];
|
|
9
|
+
let removed = 0;
|
|
10
|
+
logger.info(`workspace: ${paths.root}`);
|
|
11
|
+
for (const target of targets) {
|
|
12
|
+
if (!existsSync(target)) {
|
|
13
|
+
logger.info(`already removed: ${target}`);
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
rmSync(target, { recursive: true, force: true });
|
|
17
|
+
logger.success(`removed: ${target}`);
|
|
18
|
+
removed += 1;
|
|
19
|
+
}
|
|
20
|
+
logger.success(`remove OK · removed=${removed}/${targets.length}`);
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAM5D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAmB;IACrD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACtE,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,MAAM,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,MAAM,CAAC,OAAO,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,CAAC;IACf,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,uBAAuB,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { logger } from '../core/logger.js';
|
|
4
|
+
import { auditAgentScreenshots } from '../core/screenshot-auditor.js';
|
|
5
|
+
import { buildWorkspacePaths } from '../core/paths.js';
|
|
6
|
+
import { deriveTaskName } from '../core/route-name.js';
|
|
7
|
+
export async function screenshotsAuditCommand(opts) {
|
|
8
|
+
if (!opts.json)
|
|
9
|
+
logger.stage('Stage: screenshots-audit');
|
|
10
|
+
if (!opts.pageName && !opts.prototypeUrl) {
|
|
11
|
+
logger.error('必须提供 --url "<页面链接>" 或 --page "<页面名>" 来定位任务目录。');
|
|
12
|
+
return 2;
|
|
13
|
+
}
|
|
14
|
+
const paths = buildWorkspacePaths(opts.workspace);
|
|
15
|
+
const taskName = deriveTaskName({ pageName: opts.pageName, prototypeUrl: opts.prototypeUrl });
|
|
16
|
+
const pageDir = join(paths.pagesDir, taskName);
|
|
17
|
+
if (!existsSync(pageDir)) {
|
|
18
|
+
logger.error(`任务目录不存在:${pageDir}`);
|
|
19
|
+
return 2;
|
|
20
|
+
}
|
|
21
|
+
const audit = auditAgentScreenshots({
|
|
22
|
+
pageDir,
|
|
23
|
+
pageKey: taskName,
|
|
24
|
+
pageName: opts.pageName || taskName,
|
|
25
|
+
});
|
|
26
|
+
if (opts.json) {
|
|
27
|
+
process.stdout.write(JSON.stringify(audit, null, 2) + '\n');
|
|
28
|
+
return audit.summary.suspectedPlatformShell > 0 ? 1 : 0;
|
|
29
|
+
}
|
|
30
|
+
logger.success(`agent screenshot audit → ${audit.markdownPath}`);
|
|
31
|
+
logger.info(`screenshots=${audit.summary.total} exactGroups=${audit.summary.exactDuplicateGroups} ` +
|
|
32
|
+
`nearGroups=${audit.summary.nearDuplicateGroups} platformShell=${audit.summary.suspectedPlatformShell}`);
|
|
33
|
+
if (audit.summary.suspectedPlatformShell > 0) {
|
|
34
|
+
logger.error('发现疑似原型平台壳层截图,请删除并按 `.phone-screen` 元素重新截图。');
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=screenshots-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshots-audit.js","sourceRoot":"","sources":["../../src/commands/screenshots-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AASvD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAA6B;IACzE,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACzD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,KAAK,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,KAAK,GAAG,qBAAqB,CAAC;QAClC,OAAO;QACP,OAAO,EAAE,QAAQ;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ;KACpC,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC,OAAO,CAAC,sBAAsB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,4BAA4B,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,IAAI,CACT,eAAe,KAAK,CAAC,OAAO,CAAC,KAAK,gBAAgB,KAAK,CAAC,OAAO,CAAC,oBAAoB,GAAG;QACrF,cAAc,KAAK,CAAC,OAAO,CAAC,mBAAmB,kBAAkB,KAAK,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAC1G,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,CAAC,sBAAsB,GAAG,CAAC,EAAE,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { logger } from '../core/logger.js';
|
|
3
|
+
import { FailFastError, reportFailure } from '../core/fail-fast.js';
|
|
4
|
+
import { skillInstall } from '../core/skill-install.js';
|
|
5
|
+
export async function skillsInstallCommand(opts) {
|
|
6
|
+
const workspace = opts.workspace ? resolve(opts.workspace) : process.cwd();
|
|
7
|
+
logger.stage(`Stage: skill-install · target ${workspace}`);
|
|
8
|
+
try {
|
|
9
|
+
const res = skillInstall({ workspace });
|
|
10
|
+
logger.success(`内置 p2f skill 已安装/更新:${res.installed.length} 个目标目录。`);
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
if (err instanceof FailFastError) {
|
|
15
|
+
reportFailure(err);
|
|
16
|
+
return 1;
|
|
17
|
+
}
|
|
18
|
+
throw err;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=skills-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-install.js","sourceRoot":"","sources":["../../src/commands/skills-install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAMxD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAA0B;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3E,MAAM,CAAC,KAAK,CAAC,iCAAiC,SAAS,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,CACZ,uBAAuB,GAAG,CAAC,SAAS,CAAC,MAAM,SAAS,CACrD,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,aAAa,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { logger } from '../core/logger.js';
|
|
3
|
+
import { FailFastError, failFast, reportFailure } from '../core/fail-fast.js';
|
|
4
|
+
import { createRunContext, markComplete } from '../core/run-context.js';
|
|
5
|
+
import { checkPrdFreshness, prdClone } from '../core/prd-clone.js';
|
|
6
|
+
import { PROTOTYPE_BRANCH } from '../core/paths.js';
|
|
7
|
+
/**
|
|
8
|
+
* Check whether the local PRD prototype clone matches origin/<branch>; if not,
|
|
9
|
+
* pull the latest revision and force-reset the working tree (delegates to the
|
|
10
|
+
* existing `prdClone` update path).
|
|
11
|
+
*
|
|
12
|
+
* Designed to be safe to run repeatedly: idempotent when already up-to-date.
|
|
13
|
+
*/
|
|
14
|
+
export async function syncCommand(opts) {
|
|
15
|
+
const runOpts = {
|
|
16
|
+
pageName: '__sync__',
|
|
17
|
+
prototypeUrl: '(sync)',
|
|
18
|
+
workspace: opts.workspace,
|
|
19
|
+
kind: 'system',
|
|
20
|
+
stagePlan: ['prd-sync-check', 'prd-sync-update'],
|
|
21
|
+
};
|
|
22
|
+
const ctx = createRunContext(runOpts);
|
|
23
|
+
try {
|
|
24
|
+
if (!existsSync(ctx.paths.prdSourceDir)) {
|
|
25
|
+
failFast({
|
|
26
|
+
stage: 'prd-sync-check',
|
|
27
|
+
action: `stat ${ctx.paths.prdSourceDir}`,
|
|
28
|
+
reason: 'PRD 仓库尚未初始化,无法检查或拉取最新代码。',
|
|
29
|
+
completedSteps: [...ctx.completedSteps],
|
|
30
|
+
pendingSteps: [...ctx.pendingSteps],
|
|
31
|
+
suggestions: [
|
|
32
|
+
'先执行 `p2f init` 完成首次克隆。',
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
logger.stage('Stage: prd-sync-check');
|
|
37
|
+
const fresh = await runFreshnessCheck(ctx.paths.prdSourceDir);
|
|
38
|
+
if (fresh.upToDate) {
|
|
39
|
+
logger.success(`最新 · ${fresh.localCommit.slice(0, 7)} (origin/${PROTOTYPE_BRANCH})`);
|
|
40
|
+
markComplete(ctx, 'prd-sync-check');
|
|
41
|
+
markComplete(ctx, 'prd-sync-update');
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
logger.warn(`PRD 本地副本不是最新:local ${fresh.localCommit.slice(0, 7)} != ` +
|
|
45
|
+
`origin/${PROTOTYPE_BRANCH} ${fresh.remoteCommit.slice(0, 7)} ` +
|
|
46
|
+
`(behind ${fresh.behind}, ahead ${fresh.ahead})`);
|
|
47
|
+
markComplete(ctx, 'prd-sync-check');
|
|
48
|
+
logger.stage('Stage: prd-sync-update');
|
|
49
|
+
const result = await prdClone(ctx);
|
|
50
|
+
markComplete(ctx, 'prd-sync-update');
|
|
51
|
+
logger.success(`PRD 本地副本已更新到 origin/${result.branch} · ${result.commit.slice(0, 7)}`);
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
if (err instanceof FailFastError) {
|
|
56
|
+
reportFailure(err);
|
|
57
|
+
return 1;
|
|
58
|
+
}
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function runFreshnessCheck(prototypeDir) {
|
|
63
|
+
if (!process.env.GIT_SSH_COMMAND) {
|
|
64
|
+
process.env.GIT_SSH_COMMAND = 'ssh -o ConnectTimeout=5 -o BatchMode=yes';
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
return await checkPrdFreshness(prototypeDir);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
const msg = err.shortMessage ?? err.message;
|
|
71
|
+
failFast({
|
|
72
|
+
stage: 'prd-sync-check',
|
|
73
|
+
action: `git fetch origin ${PROTOTYPE_BRANCH} && git rev-parse`,
|
|
74
|
+
reason: `检查 PRD 仓库新鲜度失败:${msg}`,
|
|
75
|
+
suggestions: [
|
|
76
|
+
'检查网络是否可以访问 code.nexita.net。',
|
|
77
|
+
'确认当前账号有 TradeAppPrd 仓库 SSH 权限。',
|
|
78
|
+
'如有 GIT_SSH_COMMAND 自定义,确认其参数有效。',
|
|
79
|
+
],
|
|
80
|
+
needsUserDecision: ['请解决网络或仓库权限后重试。'],
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { logger } from '../core/logger.js';
|
|
3
|
+
import { checkForUpdates } from '../core/update-checker.js';
|
|
4
|
+
export async function updateCommand(opts) {
|
|
5
|
+
const json = Boolean(opts.json);
|
|
6
|
+
let result;
|
|
7
|
+
try {
|
|
8
|
+
if (!json)
|
|
9
|
+
logger.stage('Stage: update-check');
|
|
10
|
+
result = await checkForUpdates({ repo: opts.repo });
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
const message = errorMessage(err);
|
|
14
|
+
if (json) {
|
|
15
|
+
printJson({ ok: false, error: message });
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
logger.error(`检查更新失败:${message}`);
|
|
19
|
+
}
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
const shouldInstall = !opts.check && (result.updateAvailable || opts.force);
|
|
23
|
+
if (opts.check) {
|
|
24
|
+
if (json) {
|
|
25
|
+
printJson({ ok: true, installed: false, ...result });
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
printCheckResult(result);
|
|
29
|
+
}
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
if (!shouldInstall) {
|
|
33
|
+
if (json) {
|
|
34
|
+
printJson({ ok: true, installed: false, ...result });
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
logger.success(`已是最新版本 · v${result.currentVersion}`);
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
if (!json) {
|
|
43
|
+
logger.stage(`Stage: update-install · ${result.latestTag}`);
|
|
44
|
+
}
|
|
45
|
+
await installLatest(result.installSpec, json);
|
|
46
|
+
if (json) {
|
|
47
|
+
printJson({ ok: true, installed: true, ...result });
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
logger.success(`已更新到 ${result.latestTag}`);
|
|
51
|
+
}
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const message = errorMessage(err);
|
|
56
|
+
if (json) {
|
|
57
|
+
printJson({ ok: false, installed: false, error: message, ...result });
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
logger.error(`安装更新失败:${message}`);
|
|
61
|
+
}
|
|
62
|
+
return 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function printCheckResult(result) {
|
|
66
|
+
if (result.updateAvailable) {
|
|
67
|
+
logger.warn(`发现新版本 · 当前 v${result.currentVersion},最新 ${result.latestTag}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
logger.success(`已是最新版本 · v${result.currentVersion}`);
|
|
71
|
+
}
|
|
72
|
+
async function installLatest(installSpec, quiet) {
|
|
73
|
+
const args = ['install', '-g', installSpec];
|
|
74
|
+
const env = {
|
|
75
|
+
...process.env,
|
|
76
|
+
GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND ?? 'ssh -o ConnectTimeout=5 -o BatchMode=yes',
|
|
77
|
+
};
|
|
78
|
+
if (quiet) {
|
|
79
|
+
await execa('npm', args, { stdout: 'pipe', stderr: 'pipe', env });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
await execa('npm', args, { stdio: 'inherit', env });
|
|
83
|
+
}
|
|
84
|
+
function printJson(value) {
|
|
85
|
+
console.log(JSON.stringify(value, null, 2));
|
|
86
|
+
}
|
|
87
|
+
function errorMessage(err) {
|
|
88
|
+
const execaError = err;
|
|
89
|
+
const message = execaError.shortMessage ?? err.message;
|
|
90
|
+
const stderr = typeof execaError.stderr === 'string' ? execaError.stderr.trim() : '';
|
|
91
|
+
return stderr ? `${message}\n${stderr}` : message;
|
|
92
|
+
}
|
|
93
|
+
//# 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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"}
|