@niujiajie/freespec 0.0.0-stage → 1.15.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/LICENSE +22 -0
- package/README.md +58 -2
- package/bin/freespec.js +5 -0
- package/dist/cli/index.d.ts +25 -0
- package/dist/cli/index.js +359 -0
- package/dist/commands/shared-output.d.ts +18 -0
- package/dist/commands/shared-output.js +61 -0
- package/dist/commands/workflow/default-schema.d.ts +2 -0
- package/dist/commands/workflow/default-schema.js +4 -0
- package/dist/commands/workflow/index.d.ts +13 -0
- package/dist/commands/workflow/index.js +10 -0
- package/dist/commands/workflow/instructions.d.ts +39 -0
- package/dist/commands/workflow/instructions.js +565 -0
- package/dist/commands/workflow/new-change.d.ts +19 -0
- package/dist/commands/workflow/new-change.js +135 -0
- package/dist/commands/workflow/shared.d.ts +94 -0
- package/dist/commands/workflow/shared.js +169 -0
- package/dist/commands/workflow/status.d.ts +18 -0
- package/dist/commands/workflow/status.js +201 -0
- package/dist/core/artifact-graph/graph.d.ts +72 -0
- package/dist/core/artifact-graph/graph.js +165 -0
- package/dist/core/artifact-graph/index.d.ts +9 -0
- package/dist/core/artifact-graph/index.js +14 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +208 -0
- package/dist/core/artifact-graph/instruction-loader.js +268 -0
- package/dist/core/artifact-graph/outputs.d.ts +19 -0
- package/dist/core/artifact-graph/outputs.js +351 -0
- package/dist/core/artifact-graph/resolver.d.ts +89 -0
- package/dist/core/artifact-graph/resolver.js +342 -0
- package/dist/core/artifact-graph/schema.d.ts +27 -0
- package/dist/core/artifact-graph/schema.js +160 -0
- package/dist/core/artifact-graph/state.d.ts +12 -0
- package/dist/core/artifact-graph/state.js +31 -0
- package/dist/core/artifact-graph/types.d.ts +40 -0
- package/dist/core/artifact-graph/types.js +59 -0
- package/dist/core/available-tools.d.ts +18 -0
- package/dist/core/available-tools.js +49 -0
- package/dist/core/change-layout.d.ts +17 -0
- package/dist/core/change-layout.js +30 -0
- package/dist/core/change-metadata/index.d.ts +2 -0
- package/dist/core/change-metadata/index.js +2 -0
- package/dist/core/change-metadata/schema.d.ts +23 -0
- package/dist/core/change-metadata/schema.js +46 -0
- package/dist/core/change-status-policy.d.ts +49 -0
- package/dist/core/change-status-policy.js +50 -0
- package/dist/core/command-generation/adapters/amazon-q.d.ts +17 -0
- package/dist/core/command-generation/adapters/amazon-q.js +32 -0
- package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
- package/dist/core/command-generation/adapters/antigravity.js +27 -0
- package/dist/core/command-generation/adapters/atomcode.d.ts +24 -0
- package/dist/core/command-generation/adapters/atomcode.js +46 -0
- package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
- package/dist/core/command-generation/adapters/auggie.js +28 -0
- package/dist/core/command-generation/adapters/bob.d.ts +18 -0
- package/dist/core/command-generation/adapters/bob.js +33 -0
- package/dist/core/command-generation/adapters/claude.d.ts +13 -0
- package/dist/core/command-generation/adapters/claude.js +32 -0
- package/dist/core/command-generation/adapters/cline.d.ts +14 -0
- package/dist/core/command-generation/adapters/cline.js +27 -0
- package/dist/core/command-generation/adapters/codeassistant.d.ts +15 -0
- package/dist/core/command-generation/adapters/codeassistant.js +29 -0
- package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
- package/dist/core/command-generation/adapters/codebuddy.js +29 -0
- package/dist/core/command-generation/adapters/codestudio.d.ts +13 -0
- package/dist/core/command-generation/adapters/codestudio.js +27 -0
- package/dist/core/command-generation/adapters/command-code.d.ts +19 -0
- package/dist/core/command-generation/adapters/command-code.js +34 -0
- package/dist/core/command-generation/adapters/continue.d.ts +13 -0
- package/dist/core/command-generation/adapters/continue.js +33 -0
- package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
- package/dist/core/command-generation/adapters/costrict.js +28 -0
- package/dist/core/command-generation/adapters/crush.d.ts +13 -0
- package/dist/core/command-generation/adapters/crush.js +30 -0
- package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
- package/dist/core/command-generation/adapters/cursor.js +31 -0
- package/dist/core/command-generation/adapters/devin.d.ts +19 -0
- package/dist/core/command-generation/adapters/devin.js +36 -0
- package/dist/core/command-generation/adapters/easycode.d.ts +17 -0
- package/dist/core/command-generation/adapters/easycode.js +28 -0
- package/dist/core/command-generation/adapters/factory.d.ts +13 -0
- package/dist/core/command-generation/adapters/factory.js +28 -0
- package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
- package/dist/core/command-generation/adapters/gemini.js +27 -0
- package/dist/core/command-generation/adapters/gigacode.d.ts +17 -0
- package/dist/core/command-generation/adapters/gigacode.js +31 -0
- package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
- package/dist/core/command-generation/adapters/github-copilot.js +27 -0
- package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
- package/dist/core/command-generation/adapters/iflow.js +30 -0
- package/dist/core/command-generation/adapters/index.d.ts +40 -0
- package/dist/core/command-generation/adapters/index.js +40 -0
- package/dist/core/command-generation/adapters/junie.d.ts +13 -0
- package/dist/core/command-generation/adapters/junie.js +27 -0
- package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/kilocode.js +23 -0
- package/dist/core/command-generation/adapters/kiro.d.ts +13 -0
- package/dist/core/command-generation/adapters/kiro.js +27 -0
- package/dist/core/command-generation/adapters/lingma.d.ts +13 -0
- package/dist/core/command-generation/adapters/lingma.js +30 -0
- package/dist/core/command-generation/adapters/oh-my-pi.d.ts +21 -0
- package/dist/core/command-generation/adapters/oh-my-pi.js +42 -0
- package/dist/core/command-generation/adapters/opencode.d.ts +14 -0
- package/dist/core/command-generation/adapters/opencode.js +38 -0
- package/dist/core/command-generation/adapters/pi.d.ts +18 -0
- package/dist/core/command-generation/adapters/pi.js +39 -0
- package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
- package/dist/core/command-generation/adapters/qoder.js +30 -0
- package/dist/core/command-generation/adapters/qwen.d.ts +17 -0
- package/dist/core/command-generation/adapters/qwen.js +31 -0
- package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/roocode.js +27 -0
- package/dist/core/command-generation/adapters/trae.d.ts +13 -0
- package/dist/core/command-generation/adapters/trae.js +28 -0
- package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
- package/dist/core/command-generation/adapters/zcode.js +33 -0
- package/dist/core/command-generation/generator.d.ts +29 -0
- package/dist/core/command-generation/generator.js +43 -0
- package/dist/core/command-generation/index.d.ts +22 -0
- package/dist/core/command-generation/index.js +24 -0
- package/dist/core/command-generation/invocation.d.ts +73 -0
- package/dist/core/command-generation/invocation.js +77 -0
- package/dist/core/command-generation/registry.d.ts +36 -0
- package/dist/core/command-generation/registry.js +114 -0
- package/dist/core/command-generation/toml.d.ts +19 -0
- package/dist/core/command-generation/toml.js +39 -0
- package/dist/core/command-generation/types.d.ts +63 -0
- package/dist/core/command-generation/types.js +8 -0
- package/dist/core/command-generation/yaml.d.ts +36 -0
- package/dist/core/command-generation/yaml.js +48 -0
- package/dist/core/command-surface.d.ts +15 -0
- package/dist/core/command-surface.js +33 -0
- package/dist/core/config-prompts.d.ts +9 -0
- package/dist/core/config-prompts.js +56 -0
- package/dist/core/config-schema.d.ts +98 -0
- package/dist/core/config-schema.js +308 -0
- package/dist/core/config.d.ts +50 -0
- package/dist/core/config.js +122 -0
- package/dist/core/file-state.d.ts +36 -0
- package/dist/core/file-state.js +144 -0
- package/dist/core/file-view.d.ts +13 -0
- package/dist/core/file-view.js +14 -0
- package/dist/core/global-config.d.ts +101 -0
- package/dist/core/global-config.js +182 -0
- package/dist/core/id.d.ts +17 -0
- package/dist/core/id.js +30 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +7 -0
- package/dist/core/init.d.ts +57 -0
- package/dist/core/init.js +836 -0
- package/dist/core/list.d.ts +11 -0
- package/dist/core/list.js +197 -0
- package/dist/core/migration.d.ts +121 -0
- package/dist/core/migration.js +540 -0
- package/dist/core/onboarding-commands.d.ts +30 -0
- package/dist/core/onboarding-commands.js +38 -0
- package/dist/core/openspec-root.d.ts +47 -0
- package/dist/core/openspec-root.js +196 -0
- package/dist/core/planning-home.d.ts +16 -0
- package/dist/core/planning-home.js +67 -0
- package/dist/core/profile-sync-drift.d.ts +31 -0
- package/dist/core/profile-sync-drift.js +201 -0
- package/dist/core/profiles.d.ts +19 -0
- package/dist/core/profiles.js +33 -0
- package/dist/core/project-config.d.ts +132 -0
- package/dist/core/project-config.js +519 -0
- package/dist/core/references.d.ts +10 -0
- package/dist/core/references.js +46 -0
- package/dist/core/root-selection.d.ts +59 -0
- package/dist/core/root-selection.js +132 -0
- package/dist/core/shared/allowed-tools.d.ts +12 -0
- package/dist/core/shared/allowed-tools.js +12 -0
- package/dist/core/shared/ide-restart.d.ts +26 -0
- package/dist/core/shared/ide-restart.js +42 -0
- package/dist/core/shared/index.d.ts +11 -0
- package/dist/core/shared/index.js +11 -0
- package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
- package/dist/core/shared/skill-content-equivalence.js +45 -0
- package/dist/core/shared/skill-files.d.ts +7 -0
- package/dist/core/shared/skill-files.js +43 -0
- package/dist/core/shared/skill-generation.d.ts +49 -0
- package/dist/core/shared/skill-generation.js +125 -0
- package/dist/core/shared/skill-paths.d.ts +13 -0
- package/dist/core/shared/skill-paths.js +23 -0
- package/dist/core/shared/tool-detection.d.ts +99 -0
- package/dist/core/shared/tool-detection.js +318 -0
- package/dist/core/shared-skill-target.d.ts +51 -0
- package/dist/core/shared-skill-target.js +239 -0
- package/dist/core/store/errors.d.ts +20 -0
- package/dist/core/store/errors.js +22 -0
- package/dist/core/store/index.d.ts +2 -0
- package/dist/core/store/index.js +2 -0
- package/dist/core/styles/palette.d.ts +7 -0
- package/dist/core/styles/palette.js +8 -0
- package/dist/core/templates/optional-workflow.d.ts +69 -0
- package/dist/core/templates/optional-workflow.js +140 -0
- package/dist/core/templates/types.d.ts +19 -0
- package/dist/core/templates/types.js +5 -0
- package/dist/core/templates/workflows/personal.d.ts +22 -0
- package/dist/core/templates/workflows/personal.js +225 -0
- package/dist/core/update-plan.d.ts +127 -0
- package/dist/core/update-plan.js +390 -0
- package/dist/core/update.d.ts +154 -0
- package/dist/core/update.js +723 -0
- package/dist/core/version-check.d.ts +188 -0
- package/dist/core/version-check.js +906 -0
- package/dist/core/zod-issues.d.ts +4 -0
- package/dist/core/zod-issues.js +10 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/prompts/searchable-multi-select.d.ts +35 -0
- package/dist/prompts/searchable-multi-select.js +188 -0
- package/dist/telemetry/config.d.ts +37 -0
- package/dist/telemetry/config.js +148 -0
- package/dist/telemetry/index.d.ts +39 -0
- package/dist/telemetry/index.js +217 -0
- package/dist/telemetry/opt-out.d.ts +17 -0
- package/dist/telemetry/opt-out.js +27 -0
- package/dist/ui/ascii-patterns.d.ts +16 -0
- package/dist/ui/ascii-patterns.js +133 -0
- package/dist/ui/welcome-screen.d.ts +18 -0
- package/dist/ui/welcome-screen.js +199 -0
- package/dist/utils/change-metadata.d.ts +116 -0
- package/dist/utils/change-metadata.js +324 -0
- package/dist/utils/change-utils.d.ts +79 -0
- package/dist/utils/change-utils.js +121 -0
- package/dist/utils/ci.d.ts +12 -0
- package/dist/utils/ci.js +16 -0
- package/dist/utils/command-references.d.ts +104 -0
- package/dist/utils/command-references.js +190 -0
- package/dist/utils/date.d.ts +8 -0
- package/dist/utils/date.js +13 -0
- package/dist/utils/executable-path.d.ts +5 -0
- package/dist/utils/executable-path.js +44 -0
- package/dist/utils/file-system.d.ts +58 -0
- package/dist/utils/file-system.js +432 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/interactive.d.ts +85 -0
- package/dist/utils/interactive.js +174 -0
- package/dist/utils/item-discovery.d.ts +15 -0
- package/dist/utils/item-discovery.js +33 -0
- package/dist/utils/line-endings.d.ts +34 -0
- package/dist/utils/line-endings.js +46 -0
- package/dist/utils/match.d.ts +3 -0
- package/dist/utils/match.js +22 -0
- package/dist/utils/nested-change.d.ts +35 -0
- package/dist/utils/nested-change.js +185 -0
- package/dist/utils/shell-detection.d.ts +20 -0
- package/dist/utils/shell-detection.js +94 -0
- package/dist/utils/task-progress.d.ts +67 -0
- package/dist/utils/task-progress.js +184 -0
- package/package.json +74 -4
- package/schemas//351/273/230/350/256/244/schema.yaml +68 -0
- package/schemas//351/273/230/350/256/244/templates//344/273/273/345/212/241/346/270/205/345/215/225.md +25 -0
- package/schemas//351/273/230/350/256/244/templates//346/265/213/350/257/225/347/224/250/344/276/213.md +34 -0
- package/schemas//351/273/230/350/256/244/templates//350/256/276/350/256/241/346/226/207/346/241/243.md +172 -0
- package/schemas//351/273/230/350/256/244/templates//351/234/200/346/261/202/346/226/207/346/241/243.md +19 -0
- package/skill-files//344/273/273/345/212/241/references//346/212/244/346/240/217.md +43 -0
- package/skill-files//344/273/273/345/212/241/references//347/262/222/345/272/246.md +23 -0
- package/skill-files//344/273/273/345/212/241/references//347/272/246/346/235/237.md +8 -0
- package/skill-files//344/273/273/345/212/241/scripts/check-tasks.mjs +83 -0
- package/skill-files//345/206/231Java/references/Java/350/247/204/350/214/203.md +25 -0
- package/skill-files//345/206/231Java/references//345/215/261/351/231/251/345/206/231/346/263/225.md +27 -0
- package/skill-files//345/206/231Java/references//345/256/214/346/210/220/345/257/271/347/205/247.md +15 -0
- package/skill-files//345/206/231Java/references//346/212/244/346/240/217.md +35 -0
- package/skill-files//345/206/231Java/references//347/272/246/346/235/237.md +8 -0
- package/skill-files//345/206/231Java/references//350/270/251/345/235/221.md +17 -0
- package/skill-files//345/256/241Java/references//346/212/244/346/240/217.md +19 -0
- package/skill-files//345/256/241Java/references//347/244/272/344/276/213.md +23 -0
- package/skill-files//345/256/241Java/references//347/272/246/346/235/237.md +7 -0
- package/skill-files//345/256/241Java/references//350/247/204/345/210/231.md +23 -0
- package/skill-files//345/256/241Java/references//351/242/206/345/237/237/346/243/200/351/241/271.md +58 -0
- package/skill-files//345/256/241/346/226/207/346/241/243/references//346/212/244/346/240/217.md +18 -0
- package/skill-files//345/256/241/346/226/207/346/241/243/references//347/272/246/346/235/237.md +8 -0
- package/skill-files//345/256/241/346/226/207/346/241/243/references//347/273/264/345/272/246.md +17 -0
- package/skill-files//345/256/241/346/226/207/346/241/243/references//350/270/251/345/235/221.md +11 -0
- package/skill-files//346/226/260/345/273/272/references//344/272/244/346/216/245.md +11 -0
- package/skill-files//346/226/260/345/273/272/references//346/212/244/346/240/217.md +14 -0
- package/skill-files//346/226/260/345/273/272/references//347/272/246/346/235/237.md +7 -0
- package/skill-files//346/267/261/346/200/235/config/prompts.yaml +114 -0
- package/skill-files//346/267/261/346/200/235/references//344/270/211/346/226/271/346/240/270/345/257/271.md +72 -0
- package/skill-files//346/267/261/346/200/235/references//344/276/213/345/255/220.md +39 -0
- package/skill-files//346/267/261/346/200/235/references//346/200/216/344/271/210/346/203/263.md +61 -0
- package/skill-files//346/267/261/346/200/235/references//346/212/244/346/240/217.md +26 -0
- package/skill-files//346/267/261/346/200/235/references//347/202/271/351/200/211/346/217/220/351/227/256.md +66 -0
- package/skill-files//346/267/261/346/200/235/references//347/231/273/350/256/260.md +45 -0
- package/skill-files//346/267/261/346/200/235/references//347/272/246/346/235/237.md +9 -0
- package/skill-files//347/224/250/344/276/213/references//346/200/216/344/271/210/345/206/231.md +13 -0
- package/skill-files//347/224/250/344/276/213/references//346/212/244/346/240/217.md +42 -0
- package/skill-files//347/224/250/344/276/213/references//347/272/246/346/235/237.md +5 -0
- package/skill-files//347/224/250/344/276/213/scripts/check-cases.mjs +70 -0
- package/skill-files//350/256/276/350/256/241/references//345/207/206/345/244/207.md +25 -0
- package/skill-files//350/256/276/350/256/241/references//346/212/244/346/240/217.md +134 -0
- package/skill-files//350/256/276/350/256/241/references//346/226/207/351/243/216.md +17 -0
- package/skill-files//350/256/276/350/256/241/references//347/225/214/351/235/242.md +18 -0
- package/skill-files//350/256/276/350/256/241/references//347/261/273/345/236/213.md +19 -0
- package/skill-files//350/256/276/350/256/241/references//347/272/246/346/235/237.md +25 -0
- package/skill-files//350/256/276/350/256/241/scripts/_smoke.mjs +72 -0
- package/skill-files//350/256/276/350/256/241/scripts/check-design.mjs +331 -0
- package/skill-files//351/234/200/346/261/202/references//346/212/244/346/240/217.md +26 -0
- package/skill-files//351/234/200/346/261/202/references//346/226/207/351/243/216.md +23 -0
- package/skill-files//351/234/200/346/261/202/references//346/267/261/346/200/235/346/221/204/345/205/245.md +21 -0
- package/skill-files//351/234/200/346/261/202/references//347/272/246/346/235/237.md +8 -0
- package/skill-files//351/234/200/346/261/202/references//351/234/200/346/261/202/345/276/205/345/256/232.md +13 -0
- package/skill-files//351/234/200/346/261/202/scripts/check-requirements.mjs +60 -0
- package/skill-files//351/252/214/346/224/266/references//346/212/244/346/240/217.md +27 -0
- package/skill-files//351/252/214/346/224/266/references//346/240/270/345/257/271.md +17 -0
- package/skill-files//351/252/214/346/224/266/references//347/272/246/346/235/237.md +7 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RootOutput } from './root-selection.js';
|
|
2
|
+
interface ListOptions {
|
|
3
|
+
sort?: 'recent' | 'name';
|
|
4
|
+
json?: boolean;
|
|
5
|
+
root?: RootOutput;
|
|
6
|
+
}
|
|
7
|
+
export declare class ListCommand {
|
|
8
|
+
execute(targetPath?: string, options?: ListOptions): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
|
|
4
|
+
import { describeNestedChange, findNestedChanges, } from '../utils/nested-change.js';
|
|
5
|
+
import { changeParentDir, isChangeDirectoryName } from './change-layout.js';
|
|
6
|
+
function isMissingPathError(error) {
|
|
7
|
+
return (typeof error === 'object' &&
|
|
8
|
+
error !== null &&
|
|
9
|
+
'code' in error &&
|
|
10
|
+
error.code === 'ENOENT');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* An entry that cannot be dated because it no longer resolves: it was removed
|
|
14
|
+
* after `readdir` listed it, or it is a symlink whose target is missing (an
|
|
15
|
+
* Emacs `.#file` lock) or that loops back on itself.
|
|
16
|
+
*/
|
|
17
|
+
function isUnresolvableEntryError(error) {
|
|
18
|
+
if (typeof error !== 'object' || error === null || !('code' in error))
|
|
19
|
+
return false;
|
|
20
|
+
const code = error.code;
|
|
21
|
+
return code === 'ENOENT' || code === 'ELOOP';
|
|
22
|
+
}
|
|
23
|
+
async function readChangeDirectoryEntries(changesDir) {
|
|
24
|
+
try {
|
|
25
|
+
return await fs.readdir(changesDir, { withFileTypes: true });
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (isMissingPathError(error))
|
|
29
|
+
return [];
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the most recent modification time of any file in a directory (recursive).
|
|
35
|
+
* Falls back to the directory's own mtime if no files are found.
|
|
36
|
+
* Archived links use their own mtime: moving a change can break relative targets.
|
|
37
|
+
*/
|
|
38
|
+
async function getLastModified(dirPath, archived = false) {
|
|
39
|
+
let latest = null;
|
|
40
|
+
async function walk(dir) {
|
|
41
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
42
|
+
for (const entry of entries) {
|
|
43
|
+
const fullPath = path.join(dir, entry.name);
|
|
44
|
+
try {
|
|
45
|
+
if (entry.isDirectory()) {
|
|
46
|
+
await walk(fullPath);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const stat = archived && entry.isSymbolicLink()
|
|
50
|
+
? await fs.lstat(fullPath)
|
|
51
|
+
: await fs.stat(fullPath);
|
|
52
|
+
if (latest === null || stat.mtime > latest) {
|
|
53
|
+
latest = stat.mtime;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
// Skip the one entry rather than fail the listing of every change.
|
|
59
|
+
if (!isUnresolvableEntryError(error))
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
await walk(dirPath);
|
|
65
|
+
// If no files found, use the directory's own modification time
|
|
66
|
+
if (latest === null) {
|
|
67
|
+
const dirStat = await fs.stat(dirPath);
|
|
68
|
+
return dirStat.mtime;
|
|
69
|
+
}
|
|
70
|
+
return latest;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format a date as relative time (e.g., "2 hours ago", "3 days ago")
|
|
74
|
+
*/
|
|
75
|
+
function formatRelativeTime(date) {
|
|
76
|
+
const now = new Date();
|
|
77
|
+
const diffMs = now.getTime() - date.getTime();
|
|
78
|
+
const diffSecs = Math.floor(diffMs / 1000);
|
|
79
|
+
const diffMins = Math.floor(diffSecs / 60);
|
|
80
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
81
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
82
|
+
if (diffDays > 30) {
|
|
83
|
+
return date.toLocaleDateString();
|
|
84
|
+
}
|
|
85
|
+
else if (diffDays > 0) {
|
|
86
|
+
return `${diffDays}d ago`;
|
|
87
|
+
}
|
|
88
|
+
else if (diffHours > 0) {
|
|
89
|
+
return `${diffHours}h ago`;
|
|
90
|
+
}
|
|
91
|
+
else if (diffMins > 0) {
|
|
92
|
+
return `${diffMins}m ago`;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return 'just now';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export class ListCommand {
|
|
99
|
+
async execute(targetPath = '.', options = {}) {
|
|
100
|
+
const { sort = 'recent', json = false, root } = options;
|
|
101
|
+
{
|
|
102
|
+
const changesDir = changeParentDir(targetPath);
|
|
103
|
+
const entries = await readChangeDirectoryEntries(changesDir);
|
|
104
|
+
const changeDirs = entries
|
|
105
|
+
.filter(entry => entry.isDirectory() && isChangeDirectoryName(entry.name))
|
|
106
|
+
.map(entry => ({ name: entry.name, parent: changesDir, archived: false }));
|
|
107
|
+
if (changeDirs.length === 0) {
|
|
108
|
+
if (json) {
|
|
109
|
+
console.log(JSON.stringify({ changes: [], ...(root ? { root } : {}) }, null, 2));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.log('No active changes found.');
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// Collect information about each change
|
|
117
|
+
const changes = [];
|
|
118
|
+
// A directory that only wraps nested change directories is still listed -
|
|
119
|
+
// hiding it would hide a real change whenever the probe is wrong - but it
|
|
120
|
+
// is listed as what it is, so the nesting stops failing silently (#1846).
|
|
121
|
+
const nestedFindings = await findNestedChanges(changesDir, changeDirs.map((changeDir) => changeDir.name));
|
|
122
|
+
const nestedByName = new Map(nestedFindings.map((finding) => [finding.name, finding]));
|
|
123
|
+
for (const changeDir of changeDirs) {
|
|
124
|
+
const progress = await getTaskProgressForChange(changeDir.parent, changeDir.name, targetPath);
|
|
125
|
+
const changePath = path.join(changeDir.parent, changeDir.name);
|
|
126
|
+
const lastModified = await getLastModified(changePath, changeDir.archived);
|
|
127
|
+
changes.push({
|
|
128
|
+
name: changeDir.name,
|
|
129
|
+
completedTasks: progress.completed,
|
|
130
|
+
totalTasks: progress.total,
|
|
131
|
+
lastModified,
|
|
132
|
+
archived: changeDir.archived,
|
|
133
|
+
...(!changeDir.archived && nestedByName.has(changeDir.name)
|
|
134
|
+
? { nested: nestedByName.get(changeDir.name).nested }
|
|
135
|
+
: {})
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// Sort by preference (default: recent first)
|
|
139
|
+
if (sort === 'recent') {
|
|
140
|
+
changes.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
changes.sort((a, b) => a.name.localeCompare(b.name));
|
|
144
|
+
}
|
|
145
|
+
// JSON output for programmatic use
|
|
146
|
+
if (json) {
|
|
147
|
+
const jsonOutput = changes.map(c => ({
|
|
148
|
+
name: c.name,
|
|
149
|
+
completedTasks: c.completedTasks,
|
|
150
|
+
totalTasks: c.totalTasks,
|
|
151
|
+
lastModified: c.lastModified.toISOString(),
|
|
152
|
+
status: c.totalTasks === 0 ? 'no-tasks' : c.completedTasks === c.totalTasks ? 'complete' : 'in-progress',
|
|
153
|
+
...(c.nested ? { nested: c.nested } : {})
|
|
154
|
+
}));
|
|
155
|
+
// Additive: the entries keep their shape so existing consumers are
|
|
156
|
+
// unaffected, and the nesting is reported alongside them.
|
|
157
|
+
const warnings = nestedFindings.map((finding) => ({
|
|
158
|
+
code: 'nested_change_directory',
|
|
159
|
+
name: finding.name,
|
|
160
|
+
nested: finding.nested,
|
|
161
|
+
message: describeNestedChange(finding)
|
|
162
|
+
}));
|
|
163
|
+
console.log(JSON.stringify({
|
|
164
|
+
changes: jsonOutput,
|
|
165
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
166
|
+
...(root ? { root } : {})
|
|
167
|
+
}, null, 2));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Display results
|
|
171
|
+
const groups = [
|
|
172
|
+
{ heading: 'Changes:', changes: changes.filter(change => !change.archived) },
|
|
173
|
+
{ heading: 'Archived Changes:', changes: changes.filter(change => change.archived) }
|
|
174
|
+
].filter(group => group.changes.length > 0);
|
|
175
|
+
for (const [index, group] of groups.entries()) {
|
|
176
|
+
if (index > 0)
|
|
177
|
+
console.log('');
|
|
178
|
+
console.log(group.heading);
|
|
179
|
+
const padding = ' ';
|
|
180
|
+
const nameWidth = Math.max(...group.changes.map(c => c.name.length));
|
|
181
|
+
for (const change of group.changes) {
|
|
182
|
+
const paddedName = change.name.padEnd(nameWidth);
|
|
183
|
+
const status = change.nested
|
|
184
|
+
? 'not a change'
|
|
185
|
+
: formatTaskStatus({ total: change.totalTasks, completed: change.completedTasks });
|
|
186
|
+
const timeAgo = formatRelativeTime(change.lastModified);
|
|
187
|
+
console.log(`${padding}${paddedName} ${status.padEnd(12)} ${timeAgo}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
for (const finding of nestedFindings) {
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log(`Warning: ${describeNestedChange(finding)}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration Utilities
|
|
3
|
+
*
|
|
4
|
+
* One-time migration logic for existing projects when profile system is introduced.
|
|
5
|
+
* Called by both init and update commands before profile resolution.
|
|
6
|
+
*/
|
|
7
|
+
import { type AIToolOption } from './config.js';
|
|
8
|
+
import { type Delivery, type GlobalConfig, type Profile } from './global-config.js';
|
|
9
|
+
import { type FileView } from './file-view.js';
|
|
10
|
+
export interface LegacyToolRoot {
|
|
11
|
+
/** Former tool root, e.g. '.kimi' */
|
|
12
|
+
root: string;
|
|
13
|
+
/**
|
|
14
|
+
* Whether leaving this root requires the user's say-so. False when the old
|
|
15
|
+
* product is gone and its directory is certainly dead. True when the old
|
|
16
|
+
* location may still be the live one for somebody.
|
|
17
|
+
*/
|
|
18
|
+
needsConsent: boolean;
|
|
19
|
+
/** Migrations that need a freshly generated destination run afterward. */
|
|
20
|
+
timing?: 'before-generation' | 'after-generation';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Former tool roots whose FreeSpec-managed content belongs under the tool's
|
|
24
|
+
* current skillsDir. User files are never touched.
|
|
25
|
+
*/
|
|
26
|
+
export declare const LEGACY_TOOL_ROOTS: Record<string, LegacyToolRoot[]>;
|
|
27
|
+
export interface LegacyToolMigration {
|
|
28
|
+
toolId: string;
|
|
29
|
+
/** Legacy tool root, e.g. '.windsurf' */
|
|
30
|
+
from: string;
|
|
31
|
+
/** Current tool root, e.g. '.devin' */
|
|
32
|
+
to: string;
|
|
33
|
+
/** Skill directories that moved, or would move */
|
|
34
|
+
skillDirs: number;
|
|
35
|
+
/** Command files that moved, or would move */
|
|
36
|
+
commandFiles: number;
|
|
37
|
+
/**
|
|
38
|
+
* FreeSpec-managed files left under the legacy root because the copy there
|
|
39
|
+
* differs materially from the one that survives, so it is reported rather
|
|
40
|
+
* than dropped.
|
|
41
|
+
*/
|
|
42
|
+
keptInPlace: number;
|
|
43
|
+
/** Whether this move needs the user's consent first */
|
|
44
|
+
needsConsent: boolean;
|
|
45
|
+
}
|
|
46
|
+
/** One file a legacy-root migration would move or drop. */
|
|
47
|
+
export interface LegacyMigrationFileOp {
|
|
48
|
+
toolId: string;
|
|
49
|
+
source: string;
|
|
50
|
+
destination: string;
|
|
51
|
+
disposition: 'move' | 'drop';
|
|
52
|
+
/** Whether an interactive run asks before this move */
|
|
53
|
+
needsConsent: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Reports the FreeSpec content sitting under each tool's legacy root, without
|
|
57
|
+
* moving anything. Callers use this to ask before a move that needs consent.
|
|
58
|
+
*/
|
|
59
|
+
export declare function findLegacyToolMigrations(projectPath: string, timing?: 'before-generation' | 'after-generation'): LegacyToolMigration[];
|
|
60
|
+
/**
|
|
61
|
+
* Lists, file by file, what `migrateLegacyToolDirs` would move or drop, without
|
|
62
|
+
* touching anything. Consent-gated roots are included: a non-interactive run
|
|
63
|
+
* moves them without asking. `view` decides what already sits at each
|
|
64
|
+
* destination, so a dry run can plan against files it has not written.
|
|
65
|
+
*/
|
|
66
|
+
export declare function planLegacyToolMigrations(projectPath: string, timing: 'before-generation' | 'after-generation', toolIds: string[] | undefined, view: FileView): LegacyMigrationFileOp[];
|
|
67
|
+
/**
|
|
68
|
+
* Moves FreeSpec-managed skill directories (freespec-*) and command files
|
|
69
|
+
* (freespec-*) from a tool's legacy root to its current one. When the destination
|
|
70
|
+
* already exists the legacy copy is removed instead. Legacy directories are
|
|
71
|
+
* deleted only when left empty, so user files under the old location — a
|
|
72
|
+
* hand-written Cascade workflow next to the generated ones — are preserved.
|
|
73
|
+
*
|
|
74
|
+
* @param projectPath - Project root
|
|
75
|
+
* @param toolIds - Restrict the move to these tools; omit to move every tool
|
|
76
|
+
* whose legacy root needs no consent
|
|
77
|
+
*/
|
|
78
|
+
export declare function migrateLegacyToolDirs(projectPath: string, toolIds?: string[], timing?: 'before-generation' | 'after-generation'): LegacyToolMigration[];
|
|
79
|
+
/**
|
|
80
|
+
* Summarizes what a migration moved, e.g. "6 skills and 6 commands".
|
|
81
|
+
*/
|
|
82
|
+
export declare function describeLegacyMigration(migration: LegacyToolMigration): string;
|
|
83
|
+
/**
|
|
84
|
+
* Names FreeSpec-managed files the move deliberately left behind, so a user
|
|
85
|
+
* who customized one knows there are now two copies to reconcile.
|
|
86
|
+
*/
|
|
87
|
+
export declare function keptInPlaceNotice(migration: LegacyToolMigration): string | undefined;
|
|
88
|
+
/**
|
|
89
|
+
* Whether a migration has anything to move, as opposed to only files left in
|
|
90
|
+
* place. Callers use this to avoid offering a move of nothing.
|
|
91
|
+
*/
|
|
92
|
+
export declare function hasMovableContent(migration: LegacyToolMigration): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Explains why a consent-gated move is being offered, in the user's terms.
|
|
95
|
+
* Keyed by tool so the reason is specific rather than a generic "files moved".
|
|
96
|
+
*/
|
|
97
|
+
export declare function legacyMigrationNotice(migration: LegacyToolMigration): string;
|
|
98
|
+
/**
|
|
99
|
+
* Scans installed workflow files across all detected tools and returns
|
|
100
|
+
* the union of installed workflow IDs.
|
|
101
|
+
*/
|
|
102
|
+
export declare function scanInstalledWorkflows(projectPath: string, tools: AIToolOption[], view?: FileView): string[];
|
|
103
|
+
/**
|
|
104
|
+
* Performs one-time migration if the global config does not yet have a profile field.
|
|
105
|
+
* Called by both init and update before profile resolution.
|
|
106
|
+
*
|
|
107
|
+
* - If no profile field exists and workflows are installed: sets profile to 'custom'
|
|
108
|
+
* with the detected workflows, preserving the user's existing setup.
|
|
109
|
+
* - If no profile field exists and no workflows are installed: no-op (defaults apply).
|
|
110
|
+
* - If profile field already exists: no-op.
|
|
111
|
+
*/
|
|
112
|
+
export declare function computeProfileMigration(projectPath: string, tools: AIToolOption[], view?: FileView): ProfileMigration | null;
|
|
113
|
+
export type ProfileMigration = {
|
|
114
|
+
profile: Profile;
|
|
115
|
+
workflows: string[];
|
|
116
|
+
delivery?: Delivery;
|
|
117
|
+
};
|
|
118
|
+
/** The global config the one-time profile migration saves. */
|
|
119
|
+
export declare function applyProfileMigration(migration: ProfileMigration): GlobalConfig;
|
|
120
|
+
export declare function migrateIfNeeded(projectPath: string, tools: AIToolOption[]): void;
|
|
121
|
+
//# sourceMappingURL=migration.d.ts.map
|