@codewalla_india/openspec 1.3.1 → 1.3.2
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 -22
- package/README.md +272 -191
- package/bin/openspec.js +5 -5
- package/dist/cli/index.js +99 -62
- package/dist/commands/change.d.ts +0 -2
- package/dist/commands/change.js +107 -86
- package/dist/commands/config.js +14 -16
- package/dist/commands/doctor.js +9 -4
- package/dist/commands/feedback.js +79 -30
- package/dist/commands/modify.d.ts +26 -0
- package/dist/commands/modify.js +147 -0
- package/dist/commands/schema.js +170 -91
- package/dist/commands/show.js +5 -2
- package/dist/commands/spec.js +49 -29
- package/dist/commands/store.js +15 -21
- package/dist/commands/validate.d.ts +8 -0
- package/dist/commands/validate.js +43 -20
- package/dist/commands/workflow/index.d.ts +2 -2
- package/dist/commands/workflow/index.js +1 -1
- package/dist/commands/workflow/instructions.d.ts +6 -26
- package/dist/commands/workflow/instructions.js +183 -376
- package/dist/commands/workflow/new-change.d.ts +0 -4
- package/dist/commands/workflow/new-change.js +10 -28
- package/dist/commands/workflow/shared.d.ts +34 -19
- package/dist/commands/workflow/shared.js +34 -4
- package/dist/commands/workflow/status.js +10 -32
- package/dist/commands/workflow/templates.js +15 -5
- package/dist/commands/workset.d.ts +2 -2
- package/dist/commands/workset.js +19 -22
- package/dist/comprehension-quiz/fingerprint.d.ts +39 -0
- package/dist/comprehension-quiz/fingerprint.js +84 -0
- package/dist/comprehension-quiz/index.d.ts +42 -0
- package/dist/comprehension-quiz/index.js +47 -0
- package/dist/comprehension-quiz/pass-record.d.ts +44 -0
- package/dist/comprehension-quiz/pass-record.js +98 -0
- package/dist/comprehension-quiz/providers/anthropic.d.ts +34 -0
- package/dist/comprehension-quiz/providers/anthropic.js +53 -0
- package/dist/comprehension-quiz/providers/factory.d.ts +44 -0
- package/dist/comprehension-quiz/providers/factory.js +174 -0
- package/dist/comprehension-quiz/providers/interface.d.ts +59 -0
- package/dist/comprehension-quiz/providers/interface.js +63 -0
- package/dist/comprehension-quiz/providers/local.d.ts +34 -0
- package/dist/comprehension-quiz/providers/local.js +53 -0
- package/dist/comprehension-quiz/providers/ollama.d.ts +34 -0
- package/dist/comprehension-quiz/providers/ollama.js +53 -0
- package/dist/comprehension-quiz/providers/openai.d.ts +34 -0
- package/dist/comprehension-quiz/providers/openai.js +53 -0
- package/dist/comprehension-quiz/question-generator.d.ts +69 -0
- package/dist/comprehension-quiz/question-generator.js +141 -0
- package/dist/comprehension-quiz/quiz-executor.d.ts +70 -0
- package/dist/comprehension-quiz/quiz-executor.js +165 -0
- package/dist/comprehension-quiz/types.d.ts +115 -0
- package/dist/comprehension-quiz/types.js +11 -0
- package/dist/core/archive.d.ts +14 -1
- package/dist/core/archive.js +1350 -190
- package/dist/core/artifact-graph/graph.d.ts +28 -9
- package/dist/core/artifact-graph/graph.js +94 -43
- package/dist/core/artifact-graph/index.d.ts +1 -1
- package/dist/core/artifact-graph/index.js +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +30 -3
- package/dist/core/artifact-graph/instruction-loader.js +70 -12
- package/dist/core/artifact-graph/outputs.d.ts +1 -0
- package/dist/core/artifact-graph/outputs.js +67 -5
- package/dist/core/artifact-graph/resolver.d.ts +14 -0
- package/dist/core/artifact-graph/resolver.js +69 -15
- package/dist/core/artifact-graph/types.js +21 -3
- package/dist/core/available-tools.d.ts +2 -2
- package/dist/core/available-tools.js +14 -3
- package/dist/core/change-metadata/schema.d.ts +2 -0
- package/dist/core/change-metadata/schema.js +13 -0
- package/dist/core/change-status-policy.d.ts +10 -1
- package/dist/core/change-status-policy.js +30 -2
- package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
- package/dist/core/command-generation/adapters/amazon-q.js +11 -5
- package/dist/core/command-generation/adapters/antigravity.js +6 -5
- package/dist/core/command-generation/adapters/auggie.js +7 -6
- package/dist/core/command-generation/adapters/bob.d.ts +5 -1
- package/dist/core/command-generation/adapters/bob.js +11 -10
- package/dist/core/command-generation/adapters/claude.d.ts +1 -1
- package/dist/core/command-generation/adapters/claude.js +12 -17
- package/dist/core/command-generation/adapters/cline.js +5 -5
- package/dist/core/command-generation/adapters/codebuddy.js +8 -7
- package/dist/core/command-generation/adapters/continue.js +8 -7
- package/dist/core/command-generation/adapters/costrict.js +7 -6
- package/dist/core/command-generation/adapters/crush.js +9 -9
- package/dist/core/command-generation/adapters/cursor.js +8 -8
- 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/factory.js +7 -6
- package/dist/core/command-generation/adapters/gemini.js +40 -5
- package/dist/core/command-generation/adapters/github-copilot.js +6 -5
- package/dist/core/command-generation/adapters/iflow.js +9 -8
- package/dist/core/command-generation/adapters/index.d.ts +4 -2
- package/dist/core/command-generation/adapters/index.js +4 -2
- package/dist/core/command-generation/adapters/junie.js +6 -5
- package/dist/core/command-generation/adapters/kilocode.js +1 -1
- package/dist/core/command-generation/adapters/kiro.js +6 -5
- package/dist/core/command-generation/adapters/lingma.js +9 -9
- 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.js +6 -8
- package/dist/core/command-generation/adapters/pi.d.ts +2 -2
- package/dist/core/command-generation/adapters/pi.js +7 -10
- package/dist/core/command-generation/adapters/qoder.js +9 -9
- package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
- package/dist/core/command-generation/adapters/qwen.js +14 -9
- package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
- package/dist/core/command-generation/adapters/roocode.js +9 -9
- 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 +8 -0
- package/dist/core/command-generation/generator.js +15 -1
- package/dist/core/command-generation/index.d.ts +1 -1
- package/dist/core/command-generation/index.js +1 -1
- 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.js +8 -4
- package/dist/core/command-generation/types.d.ts +9 -2
- package/dist/core/command-generation/yaml.d.ts +20 -6
- package/dist/core/command-generation/yaml.js +31 -21
- package/dist/core/command-surface.d.ts +15 -0
- package/dist/core/command-surface.js +33 -0
- package/dist/core/completions/command-registry.js +16 -61
- package/dist/core/completions/generators/bash-generator.js +41 -41
- package/dist/core/completions/generators/fish-generator.js +7 -7
- package/dist/core/completions/generators/powershell-generator.js +44 -37
- package/dist/core/completions/generators/zsh-generator.js +33 -33
- package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
- package/dist/core/completions/installers/zsh-installer.js +20 -4
- package/dist/core/completions/templates/bash-templates.js +24 -24
- package/dist/core/completions/templates/fish-templates.js +38 -38
- package/dist/core/completions/templates/powershell-templates.js +28 -28
- package/dist/core/completions/templates/zsh-templates.js +39 -39
- package/dist/core/config-prompts.d.ts +1 -1
- package/dist/core/config-prompts.js +14 -1
- package/dist/core/config-schema.d.ts +10 -1
- package/dist/core/config-schema.js +67 -1
- package/dist/core/config.d.ts +15 -0
- package/dist/core/config.js +46 -5
- package/dist/core/file-state.js +56 -24
- package/dist/core/github-copilot/cloud-agent.d.ts +95 -0
- package/dist/core/github-copilot/cloud-agent.js +497 -0
- package/dist/core/global-config.d.ts +16 -0
- package/dist/core/init.d.ts +58 -0
- package/dist/core/init.js +474 -73
- package/dist/core/legacy-cleanup.d.ts +59 -0
- package/dist/core/legacy-cleanup.js +253 -24
- package/dist/core/list.js +23 -16
- package/dist/core/migration.d.ts +73 -1
- package/dist/core/migration.js +360 -11
- package/dist/core/modify/conflict-detector.d.ts +26 -0
- package/dist/core/modify/conflict-detector.js +62 -0
- package/dist/core/modify/dependency-propagator.d.ts +38 -0
- package/dist/core/modify/dependency-propagator.js +103 -0
- package/dist/core/modify/history-tracker.d.ts +34 -0
- package/dist/core/modify/history-tracker.js +114 -0
- package/dist/core/modify/index.d.ts +7 -0
- package/dist/core/modify/index.js +7 -0
- package/dist/core/onboarding-commands.d.ts +30 -0
- package/dist/core/onboarding-commands.js +38 -0
- package/dist/core/openspec-root.js +18 -15
- package/dist/core/parsers/change-parser.d.ts +17 -2
- package/dist/core/parsers/change-parser.js +35 -21
- package/dist/core/parsers/code-fence.d.ts +15 -0
- package/dist/core/parsers/code-fence.js +49 -0
- package/dist/core/parsers/markdown-parser.d.ts +0 -3
- package/dist/core/parsers/markdown-parser.js +7 -60
- package/dist/core/parsers/requirement-blocks.d.ts +29 -0
- package/dist/core/parsers/requirement-blocks.js +150 -31
- package/dist/core/parsers/requirement-text.d.ts +48 -0
- package/dist/core/parsers/requirement-text.js +98 -0
- package/dist/core/parsers/spec-structure.d.ts +1 -1
- package/dist/core/parsers/spec-structure.js +20 -30
- package/dist/core/profile-sync-drift.d.ts +0 -8
- package/dist/core/profile-sync-drift.js +49 -50
- package/dist/core/profiles.d.ts +2 -2
- package/dist/core/profiles.js +2 -2
- package/dist/core/project-config.d.ts +27 -18
- package/dist/core/project-config.js +101 -34
- package/dist/core/references.js +42 -4
- package/dist/core/relationship-health.d.ts +8 -0
- package/dist/core/relationship-health.js +13 -0
- package/dist/core/root-selection.d.ts +9 -6
- package/dist/core/root-selection.js +42 -5
- package/dist/core/schemas/base.schema.js +7 -2
- package/dist/core/shared/allowed-tools.d.ts +12 -0
- package/dist/core/shared/allowed-tools.js +12 -0
- package/dist/core/shared/index.d.ts +1 -0
- package/dist/core/shared/index.js +1 -0
- package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
- package/dist/core/shared/skill-content-equivalence.js +41 -0
- package/dist/core/shared/skill-generation.js +17 -13
- 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 +27 -7
- package/dist/core/shared/tool-detection.js +167 -37
- package/dist/core/shared-skill-target.d.ts +16 -0
- package/dist/core/shared-skill-target.js +156 -0
- package/dist/core/specs-apply.d.ts +80 -33
- package/dist/core/specs-apply.js +667 -145
- package/dist/core/store/git.d.ts +13 -0
- package/dist/core/store/git.js +24 -0
- package/dist/core/store/operations.js +20 -0
- package/dist/core/templates/skill-templates.d.ts +3 -2
- package/dist/core/templates/skill-templates.js +3 -2
- package/dist/core/templates/workflows/apply-change.d.ts +10 -0
- package/dist/core/templates/workflows/apply-change.js +186 -224
- package/dist/core/templates/workflows/archive-change.js +387 -260
- package/dist/core/templates/workflows/bulk-archive-change.js +655 -475
- package/dist/core/templates/workflows/continue-change.js +210 -219
- package/dist/core/templates/workflows/explore.js +479 -443
- package/dist/core/templates/workflows/feedback.js +97 -97
- package/dist/core/templates/workflows/ff-change.js +200 -191
- package/dist/core/templates/workflows/modify-change.d.ts +4 -1
- package/dist/core/templates/workflows/modify-change.js +237 -115
- package/dist/core/templates/workflows/new-change.js +127 -134
- package/dist/core/templates/workflows/onboard.js +548 -542
- package/dist/core/templates/workflows/propose.js +273 -217
- package/dist/core/templates/workflows/store-selection.d.ts +1 -1
- package/dist/core/templates/workflows/store-selection.js +1 -1
- package/dist/core/templates/workflows/sync-specs.js +500 -273
- package/dist/core/templates/workflows/update-change.d.ts +10 -0
- package/dist/core/templates/workflows/update-change.js +177 -0
- package/dist/core/templates/workflows/verify-change.js +324 -326
- package/dist/core/update.d.ts +40 -5
- package/dist/core/update.js +411 -96
- package/dist/core/validation/constants.d.ts +4 -1
- package/dist/core/validation/constants.js +4 -1
- package/dist/core/validation/plan-validator.d.ts +8 -0
- package/dist/core/validation/plan-validator.js +45 -0
- package/dist/core/validation/task-numbering.d.ts +16 -0
- package/dist/core/validation/task-numbering.js +57 -0
- package/dist/core/validation/validator.d.ts +27 -3
- package/dist/core/validation/validator.js +337 -48
- package/dist/core/version-check.d.ts +152 -0
- package/dist/core/version-check.js +731 -0
- package/dist/core/view.js +13 -18
- package/dist/prompts/searchable-multi-select.js +1 -1
- package/dist/telemetry/caller-detection.d.ts +27 -0
- package/dist/telemetry/caller-detection.js +85 -0
- package/dist/telemetry/caller-detection.test.d.ts +5 -0
- package/dist/telemetry/config.d.ts +48 -2
- package/dist/telemetry/config.js +113 -11
- package/dist/telemetry/config.test.d.ts +5 -0
- package/dist/telemetry/deduplication.d.ts +35 -0
- package/dist/telemetry/deduplication.js +82 -0
- package/dist/telemetry/deduplication.test.d.ts +5 -0
- package/dist/telemetry/identity.d.ts +62 -22
- package/dist/telemetry/identity.js +147 -102
- package/dist/telemetry/index.d.ts +126 -15
- package/dist/telemetry/index.js +569 -37
- package/dist/telemetry/sanitization.d.ts +40 -0
- package/dist/telemetry/sanitization.js +114 -0
- package/dist/telemetry/sanitization.test.d.ts +5 -0
- package/dist/telemetry/throttling.d.ts +20 -0
- package/dist/telemetry/throttling.js +70 -0
- package/dist/ui/welcome-screen.d.ts +9 -1
- package/dist/ui/welcome-screen.js +91 -38
- package/dist/utils/change-metadata.d.ts +43 -0
- package/dist/utils/change-metadata.js +123 -7
- package/dist/utils/change-utils.d.ts +10 -4
- package/dist/utils/change-utils.js +20 -13
- package/dist/utils/ci.d.ts +12 -0
- package/dist/utils/ci.js +16 -0
- package/dist/utils/command-references.d.ts +92 -6
- package/dist/utils/command-references.js +180 -7
- package/dist/utils/date.d.ts +8 -0
- package/dist/utils/date.js +13 -0
- package/dist/utils/file-system.d.ts +10 -0
- package/dist/utils/file-system.js +70 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/interactive.d.ts +23 -0
- package/dist/utils/interactive.js +32 -0
- package/dist/utils/item-discovery.d.ts +19 -0
- package/dist/utils/item-discovery.js +30 -48
- package/dist/utils/shell-detection.d.ts +1 -1
- package/dist/utils/shell-detection.js +64 -11
- package/dist/utils/spec-discovery.d.ts +40 -0
- package/dist/utils/spec-discovery.js +115 -0
- package/dist/utils/task-progress.d.ts +29 -1
- package/dist/utils/task-progress.js +109 -15
- package/package.json +96 -84
- package/schemas/spec-driven/schema.yaml +252 -184
- package/schemas/spec-driven/templates/design.md +19 -19
- package/schemas/spec-driven/templates/plan-template.md +91 -0
- package/schemas/spec-driven/templates/proposal.md +29 -24
- package/schemas/spec-driven/templates/spec.md +11 -8
- package/schemas/spec-driven/templates/tasks.md +9 -9
- package/scripts/postinstall.js +83 -83
- package/dist/core/command-generation/adapters/codex.d.ts +0 -16
- package/dist/core/command-generation/adapters/codex.js +0 -39
- package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
- package/dist/core/command-generation/adapters/windsurf.js +0 -38
- package/dist/core/comprehension/config.d.ts +0 -20
- package/dist/core/comprehension/config.js +0 -23
- package/dist/core/comprehension/fingerprint.d.ts +0 -14
- package/dist/core/comprehension/fingerprint.js +0 -33
- package/dist/core/comprehension/index.d.ts +0 -57
- package/dist/core/comprehension/index.js +0 -87
- package/dist/core/comprehension/pass-record.d.ts +0 -29
- package/dist/core/comprehension/pass-record.js +0 -64
- package/dist/core/comprehension/stats.d.ts +0 -35
- package/dist/core/comprehension/stats.js +0 -133
- package/dist/core/templates/workflows/comprehension-guidance.d.ts +0 -9
- package/dist/core/templates/workflows/comprehension-guidance.js +0 -73
- package/dist/core/templates/workflows/mcp-guidance.d.ts +0 -13
- package/dist/core/templates/workflows/mcp-guidance.js +0 -131
- package/dist/core/templates/workflows/user-prompt-guidance.d.ts +0 -16
- package/dist/core/templates/workflows/user-prompt-guidance.js +0 -48
- package/dist/telemetry/caller.d.ts +0 -5
- package/dist/telemetry/caller.js +0 -29
- package/dist/telemetry/client.d.ts +0 -27
- package/dist/telemetry/client.js +0 -127
- package/dist/telemetry/command-context.d.ts +0 -13
- package/dist/telemetry/command-context.js +0 -59
- package/dist/telemetry/comprehension.d.ts +0 -44
- package/dist/telemetry/comprehension.js +0 -105
- package/dist/telemetry/content.d.ts +0 -10
- package/dist/telemetry/content.js +0 -56
- package/dist/telemetry/git-stats.d.ts +0 -12
- package/dist/telemetry/git-stats.js +0 -69
- package/dist/telemetry/identify-cache.d.ts +0 -7
- package/dist/telemetry/identify-cache.js +0 -47
- package/dist/telemetry/input.d.ts +0 -17
- package/dist/telemetry/input.js +0 -68
- package/dist/telemetry/marker.d.ts +0 -37
- package/dist/telemetry/marker.js +0 -67
- package/dist/telemetry/workflow.d.ts +0 -85
- package/dist/telemetry/workflow.js +0 -318
- package/schemas/spec-driven/templates/plan.md +0 -19
package/dist/commands/doctor.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { Option } from 'commander';
|
|
7
7
|
import { resolveRootForCommand, } from '../core/root-selection.js';
|
|
8
8
|
import { readOptionalStoreMetadataState } from '../core/store/foundation.js';
|
|
9
|
-
import { gitOriginUrl, isGitRepositoryAtRoot } from '../core/store/git.js';
|
|
9
|
+
import { gitOriginUrl, gitTrackingDrift, isGitRepositoryAtRoot } from '../core/store/git.js';
|
|
10
10
|
import { classifyOpenSpecDir, readProjectConfig, resolveConfigFilePath, } from '../core/project-config.js';
|
|
11
11
|
import { findRepoPlanningRootSync } from '../core/planning-home.js';
|
|
12
12
|
import { gatherRelationshipData } from './shared-gather.js';
|
|
@@ -27,7 +27,8 @@ async function gatherHealth(root) {
|
|
|
27
27
|
referenceEntries,
|
|
28
28
|
registryUnreadable,
|
|
29
29
|
};
|
|
30
|
-
// Store facts for store-backed roots (explicit --store
|
|
30
|
+
// Store facts for store-backed roots (explicit --store, a declared
|
|
31
|
+
// pointer, or the global default).
|
|
31
32
|
// Missing/invalid metadata never reaches here: store resolution
|
|
32
33
|
// verifies identity first and fails with the existing taxonomy
|
|
33
34
|
// (recorded amendment - corrupt store.yaml is an exit-1 resolution
|
|
@@ -35,14 +36,18 @@ async function gatherHealth(root) {
|
|
|
35
36
|
if (root.storeId) {
|
|
36
37
|
const metadata = await readOptionalStoreMetadataState(root.path).catch(() => null);
|
|
37
38
|
// git -C walks UP the tree: probing a non-repo store nested inside
|
|
38
|
-
// another repo would record the ENCLOSING repo's origin.
|
|
39
|
-
const
|
|
39
|
+
// another repo would record the ENCLOSING repo's origin (and drift).
|
|
40
|
+
const isRepo = await isGitRepositoryAtRoot(root.path);
|
|
41
|
+
const [originUrl, drift] = isRepo
|
|
42
|
+
? await Promise.all([gitOriginUrl(root.path), gitTrackingDrift(root.path)])
|
|
43
|
+
: [null, null];
|
|
40
44
|
input.storeFacts = {
|
|
41
45
|
id: root.storeId,
|
|
42
46
|
metadataPresent: metadata !== null,
|
|
43
47
|
metadataValid: metadata !== null,
|
|
44
48
|
...(metadata?.remote ? { canonicalRemote: metadata.remote } : {}),
|
|
45
49
|
...(originUrl ? { originUrl } : {}),
|
|
50
|
+
...(drift ? { drift } : {}),
|
|
46
51
|
};
|
|
47
52
|
}
|
|
48
53
|
// The 3.2 both-shapes wrong turn, structured — including a malformed
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { execSync, execFileSync } from 'child_process';
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import os from 'os';
|
|
4
|
-
import { trackEvent } from '../telemetry/index.js';
|
|
5
4
|
const require = createRequire(import.meta.url);
|
|
6
5
|
/**
|
|
7
6
|
* Check if gh CLI is installed and available in PATH
|
|
@@ -60,10 +59,10 @@ function generateMetadata() {
|
|
|
60
59
|
const version = getVersion();
|
|
61
60
|
const platform = getPlatform();
|
|
62
61
|
const timestamp = getTimestamp();
|
|
63
|
-
return `---
|
|
64
|
-
Submitted via OpenSpec CLI
|
|
65
|
-
- Version: ${version}
|
|
66
|
-
- Platform: ${platform}
|
|
62
|
+
return `---
|
|
63
|
+
Submitted via OpenSpec CLI
|
|
64
|
+
- Version: ${version}
|
|
65
|
+
- Platform: ${platform}
|
|
67
66
|
- Timestamp: ${timestamp}`;
|
|
68
67
|
}
|
|
69
68
|
/**
|
|
@@ -88,7 +87,7 @@ function formatBody(bodyText) {
|
|
|
88
87
|
* Generate a pre-filled GitHub issue URL for manual submission
|
|
89
88
|
*/
|
|
90
89
|
function generateManualSubmissionUrl(title, body) {
|
|
91
|
-
const repo = 'codewalla-engineering/
|
|
90
|
+
const repo = 'codewalla-engineering/openspec-upstream-sync';
|
|
92
91
|
const encodedTitle = encodeURIComponent(title);
|
|
93
92
|
const encodedBody = encodeURIComponent(body);
|
|
94
93
|
const encodedLabels = encodeURIComponent('feedback');
|
|
@@ -106,38 +105,88 @@ function displayFormattedFeedback(title, body) {
|
|
|
106
105
|
console.log('--- END FEEDBACK ---\n');
|
|
107
106
|
}
|
|
108
107
|
/**
|
|
109
|
-
*
|
|
108
|
+
* Check whether gh refused the issue because the repository does not define
|
|
109
|
+
* the label. gh resolves label names before creating the issue, so this
|
|
110
|
+
* failure means no issue was created.
|
|
111
|
+
*
|
|
112
|
+
* Only gh's stderr is inspected. The error message also embeds the command
|
|
113
|
+
* line, which carries the user's own feedback text.
|
|
114
|
+
*/
|
|
115
|
+
function isMissingLabelError(error) {
|
|
116
|
+
return /could not add label/i.test(error?.stderr?.toString() ?? '');
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Report a gh CLI failure and exit, preserving gh's exit code.
|
|
120
|
+
*
|
|
121
|
+
* gh failed after the user already typed their feedback (issues disabled,
|
|
122
|
+
* network, rate limit, ...), so show the same manual-submission path the
|
|
123
|
+
* missing-gh and unauthenticated flows get instead of discarding the text.
|
|
124
|
+
*/
|
|
125
|
+
function reportGhFailure(error, title, body) {
|
|
126
|
+
// Display the error output from gh CLI
|
|
127
|
+
if (error.stderr) {
|
|
128
|
+
console.error(error.stderr.toString());
|
|
129
|
+
}
|
|
130
|
+
else if (error.message) {
|
|
131
|
+
console.error(error.message);
|
|
132
|
+
}
|
|
133
|
+
displayFormattedFeedback(title, body);
|
|
134
|
+
const manualUrl = generateManualSubmissionUrl(title, body);
|
|
135
|
+
console.log('Please submit your feedback manually:');
|
|
136
|
+
console.log(manualUrl);
|
|
137
|
+
// Exit with the same code as gh CLI
|
|
138
|
+
process.exit(error.status ?? 1);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Create the feedback issue via gh CLI
|
|
110
142
|
* Uses execFileSync to prevent shell injection vulnerabilities
|
|
111
143
|
*/
|
|
144
|
+
function createIssue(title, body, labels) {
|
|
145
|
+
const args = [
|
|
146
|
+
'issue',
|
|
147
|
+
'create',
|
|
148
|
+
'--repo',
|
|
149
|
+
'codewalla-engineering/openspec-upstream-sync',
|
|
150
|
+
'--title',
|
|
151
|
+
title,
|
|
152
|
+
'--body',
|
|
153
|
+
body,
|
|
154
|
+
];
|
|
155
|
+
for (const label of labels) {
|
|
156
|
+
args.push('--label', label);
|
|
157
|
+
}
|
|
158
|
+
const result = execFileSync('gh', args, { encoding: 'utf-8', stdio: 'pipe' });
|
|
159
|
+
return result.trim();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Submit feedback via gh CLI
|
|
163
|
+
*/
|
|
112
164
|
function submitViaGhCli(title, body) {
|
|
165
|
+
let issueUrl;
|
|
166
|
+
let labelApplied = true;
|
|
113
167
|
try {
|
|
114
|
-
|
|
115
|
-
'issue',
|
|
116
|
-
'create',
|
|
117
|
-
'--repo',
|
|
118
|
-
'codewalla-engineering/OpenSpec',
|
|
119
|
-
'--title',
|
|
120
|
-
title,
|
|
121
|
-
'--body',
|
|
122
|
-
body,
|
|
123
|
-
'--label',
|
|
124
|
-
'feedback',
|
|
125
|
-
], { encoding: 'utf-8', stdio: 'pipe' });
|
|
126
|
-
const issueUrl = result.trim();
|
|
127
|
-
trackEvent('feedback_submitted', { has_body: Boolean(body) });
|
|
128
|
-
console.log(`\n✓ Feedback submitted successfully!`);
|
|
129
|
-
console.log(`Issue URL: ${issueUrl}\n`);
|
|
168
|
+
issueUrl = createIssue(title, body, ['feedback']);
|
|
130
169
|
}
|
|
131
170
|
catch (error) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
171
|
+
if (!isMissingLabelError(error)) {
|
|
172
|
+
reportGhFailure(error, title, body);
|
|
173
|
+
return;
|
|
135
174
|
}
|
|
136
|
-
|
|
137
|
-
|
|
175
|
+
// The repository does not define the 'feedback' label. Nothing was
|
|
176
|
+
// created, so retry unlabeled rather than dropping the feedback.
|
|
177
|
+
try {
|
|
178
|
+
issueUrl = createIssue(title, body, []);
|
|
179
|
+
labelApplied = false;
|
|
138
180
|
}
|
|
139
|
-
|
|
140
|
-
|
|
181
|
+
catch (retryError) {
|
|
182
|
+
reportGhFailure(retryError, title, body);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
console.log(`\n✓ Feedback submitted successfully!`);
|
|
187
|
+
console.log(`Issue URL: ${issueUrl}\n`);
|
|
188
|
+
if (!labelApplied) {
|
|
189
|
+
console.log("Note: created without the 'feedback' label because the repository does not define it.\n");
|
|
141
190
|
}
|
|
142
191
|
}
|
|
143
192
|
/**
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface ModifyCommandOptions {
|
|
3
|
+
artifact: string;
|
|
4
|
+
workflowInput?: string;
|
|
5
|
+
editor?: boolean;
|
|
6
|
+
change: string;
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ModifyCommandOutput {
|
|
10
|
+
success: boolean;
|
|
11
|
+
artifactsToUpdate: Array<{
|
|
12
|
+
artifactId: string;
|
|
13
|
+
filePath: string;
|
|
14
|
+
modificationScope: 'direct' | 'propagated';
|
|
15
|
+
}>;
|
|
16
|
+
conflicts?: Array<{
|
|
17
|
+
artifactId: string;
|
|
18
|
+
affectedSections: string[];
|
|
19
|
+
}>;
|
|
20
|
+
reason?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates the modify command.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createModifyCommand(): Command;
|
|
26
|
+
//# sourceMappingURL=modify.d.ts.map
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { ArtifactGraph } from '../core/artifact-graph/graph.js';
|
|
4
|
+
import { canModify } from '../core/change-status-policy.js';
|
|
5
|
+
import { DependencyPropagator } from '../core/modify/dependency-propagator.js';
|
|
6
|
+
import { ConflictDetector } from '../core/modify/conflict-detector.js';
|
|
7
|
+
import { HistoryTracker } from '../core/modify/history-tracker.js';
|
|
8
|
+
import { resolveCurrentPlanningHomeSync } from '../core/planning-home.js';
|
|
9
|
+
import { resolveArtifactOutputPath } from '../core/artifact-graph/outputs.js';
|
|
10
|
+
import { trackArtifactModifyRequested, trackArtifactRevisionRequested, trackChangeProposalReady } from '../telemetry/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Creates the modify command.
|
|
13
|
+
*/
|
|
14
|
+
export function createModifyCommand() {
|
|
15
|
+
const command = new Command('modify')
|
|
16
|
+
.description('Modify planning artifacts before implementation starts')
|
|
17
|
+
.option('--artifact <id>', 'Artifact ID to modify')
|
|
18
|
+
.option('--workflow-input <path>', 'Workflow input file')
|
|
19
|
+
.option('--editor', 'Open in editor after modification')
|
|
20
|
+
.option('--json', 'Output JSON')
|
|
21
|
+
.argument('[change]', 'Change name')
|
|
22
|
+
.action(async (changeName, options) => {
|
|
23
|
+
const modifyOptions = {
|
|
24
|
+
artifact: options.artifact,
|
|
25
|
+
workflowInput: options.workflowInput,
|
|
26
|
+
editor: options.editor,
|
|
27
|
+
change: changeName,
|
|
28
|
+
json: options.json,
|
|
29
|
+
};
|
|
30
|
+
try {
|
|
31
|
+
const result = await executeModify(modifyOptions);
|
|
32
|
+
if (options.json) {
|
|
33
|
+
console.log(JSON.stringify(result, null, 2));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log(formatOutput(result));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
const errorOutput = {
|
|
41
|
+
success: false,
|
|
42
|
+
artifactsToUpdate: [],
|
|
43
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
44
|
+
};
|
|
45
|
+
if (options.json) {
|
|
46
|
+
console.log(JSON.stringify(errorOutput, null, 2));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.error(`Error: ${errorOutput.reason}`);
|
|
50
|
+
}
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return command;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Executes the modify command logic.
|
|
58
|
+
*/
|
|
59
|
+
async function executeModify(options) {
|
|
60
|
+
const planningHome = resolveCurrentPlanningHomeSync();
|
|
61
|
+
const changesDir = planningHome.changesDir;
|
|
62
|
+
const changeRoot = planningHome.root;
|
|
63
|
+
// Pre-apply validation: check if implementation has started
|
|
64
|
+
const canModifyResult = await canModify(options.change, changesDir);
|
|
65
|
+
if (!canModifyResult.canModify) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
artifactsToUpdate: [],
|
|
69
|
+
reason: canModifyResult.reason,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Load artifact graph
|
|
73
|
+
const schemaPath = planningHome.defaultSchema;
|
|
74
|
+
const graph = ArtifactGraph.fromYaml(schemaPath);
|
|
75
|
+
// Get artifact to modify
|
|
76
|
+
const artifactId = options.artifact;
|
|
77
|
+
if (!artifactId) {
|
|
78
|
+
throw new Error('--artifact flag is required');
|
|
79
|
+
}
|
|
80
|
+
const artifact = graph.getArtifact(artifactId);
|
|
81
|
+
if (!artifact) {
|
|
82
|
+
throw new Error(`Artifact not found: ${artifactId}`);
|
|
83
|
+
}
|
|
84
|
+
// Calculate update scope
|
|
85
|
+
const propagator = new DependencyPropagator(graph, changeRoot);
|
|
86
|
+
const updateScope = propagator.calculateUpdateScope([artifactId]);
|
|
87
|
+
// Build artifact paths map
|
|
88
|
+
const artifactPaths = new Map();
|
|
89
|
+
for (const id of updateScope) {
|
|
90
|
+
const art = graph.getArtifact(id);
|
|
91
|
+
if (art) {
|
|
92
|
+
const changeDir = join(changesDir, options.change);
|
|
93
|
+
const path = resolveArtifactOutputPath(changeDir, art.generates);
|
|
94
|
+
artifactPaths.set(id, path);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Check for conflicts
|
|
98
|
+
const conflictDetector = new ConflictDetector(changeRoot);
|
|
99
|
+
const conflicts = await conflictDetector.detectAllConflicts(artifactPaths, new Map());
|
|
100
|
+
if (conflicts.length > 0) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
artifactsToUpdate: [],
|
|
104
|
+
conflicts,
|
|
105
|
+
reason: 'Conflicts detected with manual edits. Resolve conflicts before modifying.',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// Record modification history
|
|
109
|
+
const historyTracker = new HistoryTracker(changeRoot);
|
|
110
|
+
await historyTracker.recordModification(options.change, [artifactId], options.workflowInput || 'Manual modification');
|
|
111
|
+
// Emit telemetry events
|
|
112
|
+
await trackArtifactModifyRequested(options.change, artifactId);
|
|
113
|
+
// Track proposal ready if proposal artifact is being modified
|
|
114
|
+
if (artifactId === 'proposal') {
|
|
115
|
+
await trackChangeProposalReady(options.change);
|
|
116
|
+
}
|
|
117
|
+
for (const id of updateScope) {
|
|
118
|
+
if (id !== artifactId) {
|
|
119
|
+
await trackArtifactRevisionRequested(options.change, id);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Build result
|
|
123
|
+
const artifactsToUpdate = updateScope.map((id) => ({
|
|
124
|
+
artifactId: id,
|
|
125
|
+
filePath: artifactPaths.get(id) || '',
|
|
126
|
+
modificationScope: id === artifactId ? 'direct' : 'propagated',
|
|
127
|
+
}));
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
artifactsToUpdate,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Formats the command output for human-readable display.
|
|
135
|
+
*/
|
|
136
|
+
function formatOutput(result) {
|
|
137
|
+
if (!result.success) {
|
|
138
|
+
return `Modification failed: ${result.reason}`;
|
|
139
|
+
}
|
|
140
|
+
let output = `Modification successful. ${result.artifactsToUpdate.length} artifacts to update:\n\n`;
|
|
141
|
+
for (const artifact of result.artifactsToUpdate) {
|
|
142
|
+
const scope = artifact.modificationScope === 'direct' ? 'direct' : 'propagated';
|
|
143
|
+
output += ` - ${artifact.artifactId} (${scope}): ${artifact.filePath}\n`;
|
|
144
|
+
}
|
|
145
|
+
return output;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=modify.js.map
|