silvermoon 0.1.3 → 0.2.0-rc.1
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 +40 -24
- package/README.zh-CN.md +36 -24
- package/docs/core-concepts.md +28 -11
- package/docs/getting-started.md +41 -9
- package/docs/npm-package-releases.md +8 -7
- package/docs/operations.md +60 -23
- package/docs/reference.md +125 -67
- package/docs/repository-tasks.md +29 -23
- package/package.json +3 -3
- package/schema/v1/command-report.schema.json +178 -0
- package/schema/v1/domain-message.schema.json +278 -0
- package/schema/v2/trace-event.schema.json +122 -0
- package/skills/silvermoon/SKILL.md +36 -25
- package/skills/silvermoon/references/adoption.md +8 -9
- package/src/cli.js +63 -9
- package/src/create-idea.js +260 -193
- package/src/dialogue.js +6 -305
- package/src/domain.js +592 -0
- package/src/idea-query.js +230 -0
- package/src/ideas.js +1 -0
- package/src/index.js +76 -31
- package/src/language.js +8 -0
- package/src/list-ideas.js +133 -0
- package/src/response.js +443 -0
- package/src/trace.js +90 -4
- package/src/whatsnext.js +81 -84
package/src/whatsnext.js
CHANGED
|
@@ -2,13 +2,12 @@ import { resolve } from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
ACTIVE_STATES,
|
|
5
|
-
createEnvelope,
|
|
6
5
|
diagnosticInstruction,
|
|
7
6
|
diagnosticProblem,
|
|
8
7
|
dialogueReadyObservation,
|
|
9
8
|
localize,
|
|
10
|
-
outcome,
|
|
11
9
|
} from "./dialogue.js";
|
|
10
|
+
import { createCommandRun } from "./domain.js";
|
|
12
11
|
import { inspectPhaseGuidance } from "./guidance.js";
|
|
13
12
|
import {
|
|
14
13
|
compareCommits,
|
|
@@ -236,7 +235,7 @@ function navigationInstruction(ideas, language) {
|
|
|
236
235
|
|
|
237
236
|
async function assessRepositoryReadinessInternal({
|
|
238
237
|
observed,
|
|
239
|
-
|
|
238
|
+
runtime,
|
|
240
239
|
requirePrimaryBranch = false,
|
|
241
240
|
recheckCommand = "silvermoon whats-next",
|
|
242
241
|
root,
|
|
@@ -364,22 +363,22 @@ async function assessRepositoryReadinessInternal({
|
|
|
364
363
|
branch.repository !== observed.config.primaryRepository
|
|
365
364
|
|| branch.upstreamBranch !== observed.config.primaryBranch
|
|
366
365
|
) {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
366
|
+
const actual = branch.remote === null
|
|
367
|
+
? localize(language, "none", "无")
|
|
368
|
+
: `${branch.repository ?? branch.remote}#${branch.upstreamBranch ?? localize(language, "unknown", "未知")}`;
|
|
369
|
+
localProblems.push({
|
|
370
|
+
type: "primary-upstream-mismatch",
|
|
371
|
+
summary: localize(
|
|
372
|
+
language,
|
|
373
|
+
`Branch ${branch.branch} has upstream ${actual}; expected ${observed.config.primaryRepository}#${observed.config.primaryBranch}.`,
|
|
374
|
+
`分支 ${branch.branch} 的 upstream 是 ${actual};预期为 ${observed.config.primaryRepository}#${observed.config.primaryBranch}。`,
|
|
375
|
+
),
|
|
376
|
+
});
|
|
377
|
+
localSteps.push(localize(
|
|
373
378
|
language,
|
|
374
|
-
`
|
|
375
|
-
|
|
376
|
-
)
|
|
377
|
-
});
|
|
378
|
-
localSteps.push(localize(
|
|
379
|
-
language,
|
|
380
|
-
`Configure a named remote for ${observed.config.primaryRepository}, then set branch ${branch.branch} to track that remote's ${observed.config.primaryBranch} branch. Verify with ${command(root, 'git -C "<root>" rev-parse --abbrev-ref --symbolic-full-name \'@{upstream}\'')}.`,
|
|
381
|
-
`为 ${observed.config.primaryRepository} 配置 named remote,再将分支 ${branch.branch} 的 upstream 设为该 remote 的 ${observed.config.primaryBranch}。使用 ${command(root, 'git -C "<root>" rev-parse --abbrev-ref --symbolic-full-name \'@{upstream}\'')} 验证。`,
|
|
382
|
-
));
|
|
379
|
+
`Configure a named remote for ${observed.config.primaryRepository}, then set branch ${branch.branch} to track that remote's ${observed.config.primaryBranch} branch. Verify with ${command(root, 'git -C "<root>" rev-parse --abbrev-ref --symbolic-full-name \'@{upstream}\'')}.`,
|
|
380
|
+
`为 ${observed.config.primaryRepository} 配置 named remote,再将分支 ${branch.branch} 的 upstream 设为该 remote 的 ${observed.config.primaryBranch}。使用 ${command(root, 'git -C "<root>" rev-parse --abbrev-ref --symbolic-full-name \'@{upstream}\'')} 验证。`,
|
|
381
|
+
));
|
|
383
382
|
}
|
|
384
383
|
}
|
|
385
384
|
|
|
@@ -412,29 +411,24 @@ async function assessRepositoryReadinessInternal({
|
|
|
412
411
|
};
|
|
413
412
|
}
|
|
414
413
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
language,
|
|
434
|
-
`Could not fetch configured primary: ${message}`,
|
|
435
|
-
`无法 fetch configured primary:${message}`,
|
|
436
|
-
),
|
|
437
|
-
));
|
|
414
|
+
const fetched = await runtime.performAction(
|
|
415
|
+
{
|
|
416
|
+
type: "fetch-primary",
|
|
417
|
+
repository: observed.config.primaryRepository,
|
|
418
|
+
branch: observed.config.primaryBranch,
|
|
419
|
+
},
|
|
420
|
+
() => ({
|
|
421
|
+
commit: fetchPrimary(root, observed.config),
|
|
422
|
+
}),
|
|
423
|
+
(caught) => ({
|
|
424
|
+
problem: {
|
|
425
|
+
type: "primary-fetch-failed",
|
|
426
|
+
summary: sanitizeGitMessage(caught.message),
|
|
427
|
+
},
|
|
428
|
+
}),
|
|
429
|
+
);
|
|
430
|
+
if (fetched.status === "failure") {
|
|
431
|
+
const message = fetched.problem.summary;
|
|
438
432
|
return {
|
|
439
433
|
observation: repositoryProblemObservation(observed.observation, [{
|
|
440
434
|
type: "primary-fetch-failed",
|
|
@@ -448,6 +442,7 @@ async function assessRepositoryReadinessInternal({
|
|
|
448
442
|
ready: false,
|
|
449
443
|
};
|
|
450
444
|
}
|
|
445
|
+
const primary = fetched.result.commit;
|
|
451
446
|
|
|
452
447
|
let relation;
|
|
453
448
|
try {
|
|
@@ -556,30 +551,31 @@ export async function whatsNext({
|
|
|
556
551
|
language: canonicalLanguage ?? null,
|
|
557
552
|
},
|
|
558
553
|
};
|
|
554
|
+
const runtime = createCommandRun(intention);
|
|
559
555
|
const baseRecheckCommand = selector === undefined
|
|
560
556
|
? "silvermoon whats-next"
|
|
561
557
|
: `silvermoon whats-next ${JSON.stringify(selector)}`;
|
|
562
558
|
const recheckCommand = canonicalLanguage === undefined
|
|
563
559
|
? baseRecheckCommand
|
|
564
560
|
: `${baseRecheckCommand} --language ${canonicalLanguage}`;
|
|
565
|
-
const outcomes = [];
|
|
566
561
|
let observed = await observeSnapshot({
|
|
567
562
|
outputLanguage: canonicalLanguage,
|
|
568
563
|
root: requestedRoot,
|
|
569
564
|
userHome,
|
|
570
565
|
version: { type: "worktree" },
|
|
571
566
|
});
|
|
567
|
+
runtime.observe(observed.observation, { factType: "project.snapshot" });
|
|
572
568
|
if (!observed.projectReady) {
|
|
573
|
-
return
|
|
574
|
-
intention,
|
|
569
|
+
return runtime.complete(
|
|
575
570
|
observed.observation,
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
571
|
+
{
|
|
572
|
+
nextSteps: projectInstructions(
|
|
573
|
+
observed,
|
|
574
|
+
observed.observation.root,
|
|
575
|
+
observed.outputLanguage,
|
|
576
|
+
recheckCommand,
|
|
577
|
+
),
|
|
578
|
+
},
|
|
583
579
|
);
|
|
584
580
|
}
|
|
585
581
|
|
|
@@ -589,42 +585,43 @@ export async function whatsNext({
|
|
|
589
585
|
}
|
|
590
586
|
const readiness = await assessRepositoryReadiness({
|
|
591
587
|
observed,
|
|
592
|
-
|
|
588
|
+
runtime,
|
|
593
589
|
recheckCommand,
|
|
594
590
|
root: observed.observation.root,
|
|
595
591
|
});
|
|
596
592
|
if (!readiness.ready) {
|
|
597
|
-
return
|
|
598
|
-
intention,
|
|
593
|
+
return runtime.complete(
|
|
599
594
|
readiness.observation,
|
|
600
|
-
|
|
601
|
-
readiness.instructions,
|
|
595
|
+
{ nextSteps: readiness.instructions },
|
|
602
596
|
);
|
|
603
597
|
}
|
|
604
598
|
|
|
605
599
|
if (selector === undefined) {
|
|
606
|
-
return
|
|
607
|
-
intention,
|
|
600
|
+
return runtime.complete(
|
|
608
601
|
{ ...readiness.observation, state: "navigation-ready" },
|
|
609
|
-
|
|
610
|
-
|
|
602
|
+
{
|
|
603
|
+
nextSteps: navigationInstruction(
|
|
604
|
+
observed.layout.ideas,
|
|
605
|
+
observed.outputLanguage,
|
|
606
|
+
),
|
|
607
|
+
},
|
|
611
608
|
);
|
|
612
609
|
}
|
|
613
610
|
if (!selected) {
|
|
614
|
-
return
|
|
615
|
-
intention,
|
|
611
|
+
return runtime.complete(
|
|
616
612
|
dialogueReadyObservation(readiness.observation, "idea-not-found", {
|
|
617
613
|
candidates: readiness.observation.ideas.activeIdeas,
|
|
618
614
|
}),
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
615
|
+
{
|
|
616
|
+
nextSteps: joinInstructions([
|
|
617
|
+
localize(
|
|
618
|
+
observed.outputLanguage,
|
|
619
|
+
`Idea ${selector} does not match an observed ULID or unique alias.`,
|
|
620
|
+
`Idea ${selector} 未匹配任何已观察到的 ULID 或唯一 alias。`,
|
|
621
|
+
),
|
|
622
|
+
navigationInstruction(observed.layout.ideas, observed.outputLanguage),
|
|
623
|
+
]),
|
|
624
|
+
},
|
|
628
625
|
);
|
|
629
626
|
}
|
|
630
627
|
|
|
@@ -641,8 +638,7 @@ export async function whatsNext({
|
|
|
641
638
|
snapshotTree: readiness.primary,
|
|
642
639
|
});
|
|
643
640
|
if (inspected.state === "invalid") {
|
|
644
|
-
return
|
|
645
|
-
intention,
|
|
641
|
+
return runtime.complete(
|
|
646
642
|
dialogueReadyObservation(
|
|
647
643
|
readiness.observation,
|
|
648
644
|
"phase-guidance-invalid",
|
|
@@ -653,24 +649,25 @@ export async function whatsNext({
|
|
|
653
649
|
),
|
|
654
650
|
},
|
|
655
651
|
),
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
652
|
+
{
|
|
653
|
+
nextSteps: phaseGuidanceInstructions(
|
|
654
|
+
inspected.diagnostics,
|
|
655
|
+
readiness.observation.root,
|
|
656
|
+
observed.outputLanguage,
|
|
657
|
+
recheckCommand,
|
|
658
|
+
),
|
|
659
|
+
},
|
|
663
660
|
);
|
|
664
661
|
}
|
|
665
662
|
guidance = inspected.guidance;
|
|
666
663
|
}
|
|
667
|
-
return
|
|
668
|
-
intention,
|
|
664
|
+
return runtime.complete(
|
|
669
665
|
dialogueReadyObservation(readiness.observation, "idea-selected", {
|
|
670
666
|
selectedIdea,
|
|
671
667
|
...(guidance === undefined ? {} : { guidance }),
|
|
672
668
|
}),
|
|
673
|
-
|
|
674
|
-
|
|
669
|
+
{
|
|
670
|
+
nextSteps: lifecycleInstruction(selected, observed.outputLanguage),
|
|
671
|
+
},
|
|
675
672
|
);
|
|
676
673
|
}
|