@ai-content-space/loopx 0.2.8 → 0.2.10

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.
Files changed (105) hide show
  1. package/README.md +26 -9
  2. package/README.zh-CN.md +26 -9
  3. package/docs/loopx/design/loopx-skill-suite-v1-design.md +12 -0
  4. package/docs/loopx/plans/2026-06-14-loopx-spec-memory-context-loading.md +948 -0
  5. package/docs/loopx/plans/2026-06-15-support-lens-skills-migration.md +1153 -0
  6. package/package.json +6 -1
  7. package/plugins/loopx/.codex-plugin/plugin.json +1 -1
  8. package/plugins/loopx/skills/api-designer/SKILL.md +232 -0
  9. package/plugins/loopx/skills/api-designer/references/error-handling.md +541 -0
  10. package/plugins/loopx/skills/api-designer/references/openapi.md +824 -0
  11. package/plugins/loopx/skills/api-designer/references/pagination.md +494 -0
  12. package/plugins/loopx/skills/api-designer/references/rest-patterns.md +335 -0
  13. package/plugins/loopx/skills/api-designer/references/versioning.md +391 -0
  14. package/plugins/loopx/skills/architecture-designer/SKILL.md +117 -0
  15. package/plugins/loopx/skills/architecture-designer/references/adr-template.md +116 -0
  16. package/plugins/loopx/skills/architecture-designer/references/architecture-patterns.md +346 -0
  17. package/plugins/loopx/skills/architecture-designer/references/database-selection.md +102 -0
  18. package/plugins/loopx/skills/architecture-designer/references/nfr-checklist.md +212 -0
  19. package/plugins/loopx/skills/architecture-designer/references/system-design.md +313 -0
  20. package/plugins/loopx/skills/clarify/SKILL.md +12 -1
  21. package/plugins/loopx/skills/cli-developer/SKILL.md +124 -0
  22. package/plugins/loopx/skills/cli-developer/references/design-patterns.md +221 -0
  23. package/plugins/loopx/skills/cli-developer/references/go-cli.md +540 -0
  24. package/plugins/loopx/skills/cli-developer/references/node-cli.md +383 -0
  25. package/plugins/loopx/skills/cli-developer/references/python-cli.md +422 -0
  26. package/plugins/loopx/skills/cli-developer/references/ux-patterns.md +448 -0
  27. package/plugins/loopx/skills/debug/SKILL.md +1 -1
  28. package/plugins/loopx/skills/doc-readability/SKILL.md +1 -1
  29. package/plugins/loopx/skills/exec/SKILL.md +1 -1
  30. package/plugins/loopx/skills/final-review/SKILL.md +1 -1
  31. package/plugins/loopx/skills/finish/SKILL.md +1 -1
  32. package/plugins/loopx/skills/fix-review/SKILL.md +1 -1
  33. package/plugins/loopx/skills/go-style/SKILL.md +1 -1
  34. package/plugins/loopx/skills/kratos/SKILL.md +2 -1
  35. package/plugins/loopx/skills/plan-to-exec/SKILL.md +12 -1
  36. package/plugins/loopx/skills/refactor-plan/SKILL.md +1 -1
  37. package/plugins/loopx/skills/requirement-analyzer/SKILL.md +161 -0
  38. package/plugins/loopx/skills/requirement-analyzer/references/example-reports.md +170 -0
  39. package/plugins/loopx/skills/requirement-analyzer/references/prd-gap-checklist.md +167 -0
  40. package/plugins/loopx/skills/requirement-analyzer/references/readiness-rubric.md +70 -0
  41. package/plugins/loopx/skills/requirement-analyzer/references/report-template.md +83 -0
  42. package/plugins/loopx/skills/review/SKILL.md +1 -1
  43. package/plugins/loopx/skills/spec/SKILL.md +12 -1
  44. package/plugins/loopx/skills/sql-style/SKILL.md +108 -0
  45. package/plugins/loopx/skills/sql-style/references/database-design.md +402 -0
  46. package/plugins/loopx/skills/sql-style/references/dialect-differences.md +419 -0
  47. package/plugins/loopx/skills/sql-style/references/optimization.md +384 -0
  48. package/plugins/loopx/skills/sql-style/references/query-patterns.md +285 -0
  49. package/plugins/loopx/skills/sql-style/references/window-functions.md +328 -0
  50. package/plugins/loopx/skills/subagent-exec/SKILL.md +1 -1
  51. package/plugins/loopx/skills/tdd/SKILL.md +1 -1
  52. package/plugins/loopx/skills/verify/SKILL.md +1 -1
  53. package/scripts/verify-skills.mjs +0 -2
  54. package/skills/RESOLVER.md +8 -1
  55. package/skills/api-designer/SKILL.md +232 -0
  56. package/skills/api-designer/references/error-handling.md +541 -0
  57. package/skills/api-designer/references/openapi.md +824 -0
  58. package/skills/api-designer/references/pagination.md +494 -0
  59. package/skills/api-designer/references/rest-patterns.md +335 -0
  60. package/skills/api-designer/references/versioning.md +391 -0
  61. package/skills/architecture-designer/SKILL.md +117 -0
  62. package/skills/architecture-designer/references/adr-template.md +116 -0
  63. package/skills/architecture-designer/references/architecture-patterns.md +346 -0
  64. package/skills/architecture-designer/references/database-selection.md +102 -0
  65. package/skills/architecture-designer/references/nfr-checklist.md +212 -0
  66. package/skills/architecture-designer/references/system-design.md +313 -0
  67. package/skills/clarify/SKILL.md +12 -1
  68. package/skills/cli-developer/SKILL.md +124 -0
  69. package/skills/cli-developer/references/design-patterns.md +221 -0
  70. package/skills/cli-developer/references/go-cli.md +540 -0
  71. package/skills/cli-developer/references/node-cli.md +383 -0
  72. package/skills/cli-developer/references/python-cli.md +422 -0
  73. package/skills/cli-developer/references/ux-patterns.md +448 -0
  74. package/skills/debug/SKILL.md +1 -1
  75. package/skills/doc-readability/SKILL.md +1 -1
  76. package/skills/exec/SKILL.md +1 -1
  77. package/skills/final-review/SKILL.md +1 -1
  78. package/skills/finish/SKILL.md +1 -1
  79. package/skills/fix-review/SKILL.md +1 -1
  80. package/skills/go-style/SKILL.md +1 -1
  81. package/skills/kratos/SKILL.md +2 -1
  82. package/skills/plan-to-exec/SKILL.md +12 -1
  83. package/skills/refactor-plan/SKILL.md +1 -1
  84. package/skills/requirement-analyzer/SKILL.md +161 -0
  85. package/skills/requirement-analyzer/references/example-reports.md +170 -0
  86. package/skills/requirement-analyzer/references/prd-gap-checklist.md +167 -0
  87. package/skills/requirement-analyzer/references/readiness-rubric.md +70 -0
  88. package/skills/requirement-analyzer/references/report-template.md +83 -0
  89. package/skills/review/SKILL.md +1 -1
  90. package/skills/spec/SKILL.md +12 -1
  91. package/skills/sql-style/SKILL.md +108 -0
  92. package/skills/sql-style/references/database-design.md +402 -0
  93. package/skills/sql-style/references/dialect-differences.md +419 -0
  94. package/skills/sql-style/references/optimization.md +384 -0
  95. package/skills/sql-style/references/query-patterns.md +285 -0
  96. package/skills/sql-style/references/window-functions.md +328 -0
  97. package/skills/subagent-exec/SKILL.md +1 -1
  98. package/skills/tdd/SKILL.md +1 -1
  99. package/skills/verify/SKILL.md +1 -1
  100. package/src/cli.mjs +4 -1
  101. package/src/context-manifest.mjs +51 -1
  102. package/src/install-discovery.mjs +114 -0
  103. package/src/loopx-context-artifacts.mjs +114 -0
  104. package/src/project-discovery.mjs +1 -0
  105. package/src/workflow.mjs +47 -3
@@ -0,0 +1,540 @@
1
+ # Go CLI Development
2
+
3
+ ## Cobra (Recommended)
4
+
5
+ Powerful CLI framework used by kubectl, hugo, docker.
6
+
7
+ ```go
8
+ // cmd/root.go
9
+ package cmd
10
+
11
+ import (
12
+ "fmt"
13
+ "os"
14
+ "github.com/spf13/cobra"
15
+ "github.com/spf13/viper"
16
+ )
17
+
18
+ var (
19
+ cfgFile string
20
+ verbose bool
21
+ )
22
+
23
+ var rootCmd = &cobra.Command{
24
+ Use: "mycli",
25
+ Short: "My awesome CLI tool",
26
+ Long: `A longer description of your CLI application`,
27
+ Version: "1.0.0",
28
+ }
29
+
30
+ func Execute() {
31
+ if err := rootCmd.Execute(); err != nil {
32
+ fmt.Fprintln(os.Stderr, err)
33
+ os.Exit(1)
34
+ }
35
+ }
36
+
37
+ func init() {
38
+ cobra.OnInitialize(initConfig)
39
+
40
+ rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
41
+ rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
42
+
43
+ viper.BindPFlag("verbose", rootCmd.PersistentFlags().Lookup("verbose"))
44
+ }
45
+
46
+ func initConfig() {
47
+ if cfgFile != "" {
48
+ viper.SetConfigFile(cfgFile)
49
+ } else {
50
+ home, err := os.UserHomeDir()
51
+ cobra.CheckErr(err)
52
+
53
+ viper.AddConfigPath(home)
54
+ viper.AddConfigPath(".")
55
+ viper.SetConfigType("yaml")
56
+ viper.SetConfigName(".mycli")
57
+ }
58
+
59
+ viper.AutomaticEnv()
60
+
61
+ if err := viper.ReadInConfig(); err == nil {
62
+ fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
63
+ }
64
+ }
65
+
66
+ // cmd/init.go
67
+ package cmd
68
+
69
+ import (
70
+ "fmt"
71
+ "github.com/spf13/cobra"
72
+ )
73
+
74
+ var (
75
+ template string
76
+ force bool
77
+ )
78
+
79
+ var initCmd = &cobra.Command{
80
+ Use: "init [name]",
81
+ Short: "Initialize a new project",
82
+ Args: cobra.ExactArgs(1),
83
+ RunE: func(cmd *cobra.Command, args []string) error {
84
+ name := args[0]
85
+ return initProject(name, template, force)
86
+ },
87
+ }
88
+
89
+ func init() {
90
+ rootCmd.AddCommand(initCmd)
91
+
92
+ initCmd.Flags().StringVarP(&template, "template", "t", "default", "Project template")
93
+ initCmd.Flags().BoolVarP(&force, "force", "f", false, "Overwrite existing")
94
+ }
95
+
96
+ func initProject(name, template string, force bool) error {
97
+ fmt.Printf("Creating %s from %s\n", name, template)
98
+ return nil
99
+ }
100
+
101
+ // cmd/deploy.go
102
+ package cmd
103
+
104
+ import (
105
+ "fmt"
106
+ "github.com/spf13/cobra"
107
+ )
108
+
109
+ var (
110
+ dryRun bool
111
+ )
112
+
113
+ var deployCmd = &cobra.Command{
114
+ Use: "deploy [environment]",
115
+ Short: "Deploy to environment",
116
+ Args: cobra.ExactArgs(1),
117
+ ValidArgs: []string{"dev", "staging", "prod"},
118
+ RunE: func(cmd *cobra.Command, args []string) error {
119
+ env := args[0]
120
+ return deploy(env, dryRun)
121
+ },
122
+ }
123
+
124
+ func init() {
125
+ rootCmd.AddCommand(deployCmd)
126
+ deployCmd.Flags().BoolVar(&dryRun, "dry-run", false, "Preview only")
127
+ }
128
+
129
+ func deploy(env string, dryRun bool) error {
130
+ if dryRun {
131
+ fmt.Printf("Would deploy to: %s\n", env)
132
+ } else {
133
+ fmt.Printf("Deploying to %s...\n", env)
134
+ }
135
+ return nil
136
+ }
137
+
138
+ // main.go
139
+ package main
140
+
141
+ import "mycli/cmd"
142
+
143
+ func main() {
144
+ cmd.Execute()
145
+ }
146
+ ```
147
+
148
+ ## Viper (Configuration)
149
+
150
+ Configuration management with multiple sources.
151
+
152
+ ```go
153
+ package config
154
+
155
+ import (
156
+ "fmt"
157
+ "github.com/spf13/viper"
158
+ )
159
+
160
+ type Config struct {
161
+ Environment string `mapstructure:"environment"`
162
+ Timeout int `mapstructure:"timeout"`
163
+ Verbose bool `mapstructure:"verbose"`
164
+ API APIConfig `mapstructure:"api"`
165
+ }
166
+
167
+ type APIConfig struct {
168
+ Endpoint string `mapstructure:"endpoint"`
169
+ Token string `mapstructure:"token"`
170
+ }
171
+
172
+ func Load() (*Config, error) {
173
+ // Set defaults
174
+ viper.SetDefault("environment", "development")
175
+ viper.SetDefault("timeout", 30)
176
+ viper.SetDefault("verbose", false)
177
+
178
+ // Config file locations
179
+ viper.SetConfigName("config")
180
+ viper.SetConfigType("yaml")
181
+ viper.AddConfigPath("/etc/mycli/")
182
+ viper.AddConfigPath("$HOME/.config/mycli")
183
+ viper.AddConfigPath(".")
184
+
185
+ // Environment variables
186
+ viper.SetEnvPrefix("MYCLI")
187
+ viper.AutomaticEnv()
188
+
189
+ // Read config
190
+ if err := viper.ReadInConfig(); err != nil {
191
+ if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
192
+ return nil, fmt.Errorf("failed to read config: %w", err)
193
+ }
194
+ }
195
+
196
+ // Unmarshal into struct
197
+ var cfg Config
198
+ if err := viper.Unmarshal(&cfg); err != nil {
199
+ return nil, fmt.Errorf("failed to unmarshal config: %w", err)
200
+ }
201
+
202
+ return &cfg, nil
203
+ }
204
+ ```
205
+
206
+ ## Bubble Tea (Interactive TUI)
207
+
208
+ Modern terminal UI framework for interactive CLIs.
209
+
210
+ ```go
211
+ package main
212
+
213
+ import (
214
+ "fmt"
215
+ "os"
216
+
217
+ tea "github.com/charmbracelet/bubbletea"
218
+ "github.com/charmbracelet/lipgloss"
219
+ )
220
+
221
+ // Model
222
+ type model struct {
223
+ choices []string
224
+ cursor int
225
+ selected map[int]struct{}
226
+ }
227
+
228
+ func initialModel() model {
229
+ return model{
230
+ choices: []string{"TypeScript", "ESLint", "Prettier", "Jest"},
231
+ selected: make(map[int]struct{}),
232
+ }
233
+ }
234
+
235
+ // Init
236
+ func (m model) Init() tea.Cmd {
237
+ return nil
238
+ }
239
+
240
+ // Update
241
+ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
242
+ switch msg := msg.(type) {
243
+ case tea.KeyMsg:
244
+ switch msg.String() {
245
+ case "ctrl+c", "q":
246
+ return m, tea.Quit
247
+
248
+ case "up", "k":
249
+ if m.cursor > 0 {
250
+ m.cursor--
251
+ }
252
+
253
+ case "down", "j":
254
+ if m.cursor < len(m.choices)-1 {
255
+ m.cursor++
256
+ }
257
+
258
+ case " ":
259
+ _, ok := m.selected[m.cursor]
260
+ if ok {
261
+ delete(m.selected, m.cursor)
262
+ } else {
263
+ m.selected[m.cursor] = struct{}{}
264
+ }
265
+
266
+ case "enter":
267
+ return m, tea.Quit
268
+ }
269
+ }
270
+
271
+ return m, nil
272
+ }
273
+
274
+ // View
275
+ func (m model) View() string {
276
+ s := "Select features:\n\n"
277
+
278
+ for i, choice := range m.choices {
279
+ cursor := " "
280
+ if m.cursor == i {
281
+ cursor = ">"
282
+ }
283
+
284
+ checked := " "
285
+ if _, ok := m.selected[i]; ok {
286
+ checked = "x"
287
+ }
288
+
289
+ s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
290
+ }
291
+
292
+ s += "\nPress space to select, enter to confirm, q to quit.\n"
293
+
294
+ return s
295
+ }
296
+
297
+ func main() {
298
+ p := tea.NewProgram(initialModel())
299
+ if _, err := p.Run(); err != nil {
300
+ fmt.Printf("Error: %v", err)
301
+ os.Exit(1)
302
+ }
303
+ }
304
+ ```
305
+
306
+ ## Progress Indicators
307
+
308
+ ```go
309
+ package main
310
+
311
+ import (
312
+ "fmt"
313
+ "time"
314
+
315
+ "github.com/schollz/progressbar/v3"
316
+ )
317
+
318
+ func main() {
319
+ // Simple progress bar
320
+ bar := progressbar.Default(100, "Downloading")
321
+ for i := 0; i < 100; i++ {
322
+ bar.Add(1)
323
+ time.Sleep(40 * time.Millisecond)
324
+ }
325
+
326
+ // Custom progress bar
327
+ bar = progressbar.NewOptions(100,
328
+ progressbar.OptionEnableColorCodes(true),
329
+ progressbar.OptionShowBytes(true),
330
+ progressbar.OptionSetWidth(15),
331
+ progressbar.OptionSetDescription("[cyan][1/3][reset] Downloading..."),
332
+ progressbar.OptionSetTheme(progressbar.Theme{
333
+ Saucer: "[green]=[reset]",
334
+ SaucerHead: "[green]>[reset]",
335
+ SaucerPadding: " ",
336
+ BarStart: "[",
337
+ BarEnd: "]",
338
+ }),
339
+ )
340
+
341
+ for i := 0; i < 100; i++ {
342
+ bar.Add(1)
343
+ time.Sleep(40 * time.Millisecond)
344
+ }
345
+ }
346
+ ```
347
+
348
+ ## Spinner
349
+
350
+ ```go
351
+ package main
352
+
353
+ import (
354
+ "fmt"
355
+ "time"
356
+
357
+ "github.com/briandowns/spinner"
358
+ )
359
+
360
+ func main() {
361
+ s := spinner.New(spinner.CharSets[11], 100*time.Millisecond)
362
+ s.Suffix = " Installing dependencies..."
363
+ s.Start()
364
+
365
+ time.Sleep(4 * time.Second)
366
+
367
+ s.UpdateCharSet(spinner.CharSets[9])
368
+ s.Suffix = " Processing..."
369
+ time.Sleep(2 * time.Second)
370
+
371
+ s.Stop()
372
+ fmt.Println("✓ Done!")
373
+ }
374
+ ```
375
+
376
+ ## Colored Output
377
+
378
+ ```go
379
+ package main
380
+
381
+ import (
382
+ "github.com/fatih/color"
383
+ )
384
+
385
+ func main() {
386
+ // Basic colors
387
+ color.Blue("Info: Starting deployment...")
388
+ color.Green("Success: Deployment complete!")
389
+ color.Yellow("Warning: Deprecated flag used")
390
+ color.Red("Error: Deployment failed")
391
+
392
+ // Custom styles
393
+ success := color.New(color.FgGreen, color.Bold).PrintlnFunc()
394
+ error := color.New(color.FgRed, color.Bold).PrintlnFunc()
395
+
396
+ success("✓ Build successful")
397
+ error("✗ Build failed")
398
+
399
+ // Printf-style
400
+ color.Cyan("Processing %d files...\n", 42)
401
+
402
+ // Disable colors for CI
403
+ if os.Getenv("CI") != "" {
404
+ color.NoColor = true
405
+ }
406
+ }
407
+ ```
408
+
409
+ ## Error Handling
410
+
411
+ ```go
412
+ package main
413
+
414
+ import (
415
+ "errors"
416
+ "fmt"
417
+ "os"
418
+ "syscall"
419
+
420
+ "github.com/spf13/cobra"
421
+ )
422
+
423
+ var deployCmd = &cobra.Command{
424
+ Use: "deploy",
425
+ Short: "Deploy application",
426
+ RunE: func(cmd *cobra.Command, args []string) error {
427
+ if err := deploy(); err != nil {
428
+ return handleError(err)
429
+ }
430
+ return nil
431
+ },
432
+ }
433
+
434
+ func handleError(err error) error {
435
+ var exitCode int
436
+
437
+ switch {
438
+ case errors.Is(err, os.ErrPermission):
439
+ fmt.Fprintln(os.Stderr, "Permission denied")
440
+ fmt.Fprintln(os.Stderr, "Try running with sudo or check file permissions")
441
+ exitCode = 77
442
+
443
+ case errors.Is(err, os.ErrNotExist):
444
+ fmt.Fprintf(os.Stderr, "File not found: %v\n", err)
445
+ exitCode = 127
446
+
447
+ default:
448
+ fmt.Fprintf(os.Stderr, "Deployment failed: %v\n", err)
449
+ if os.Getenv("DEBUG") != "" {
450
+ fmt.Fprintf(os.Stderr, "%+v\n", err)
451
+ }
452
+ exitCode = 1
453
+ }
454
+
455
+ os.Exit(exitCode)
456
+ return nil
457
+ }
458
+
459
+ // Handle SIGINT (Ctrl+C)
460
+ func main() {
461
+ // Setup signal handling
462
+ c := make(chan os.Signal, 1)
463
+ signal.Notify(c, os.Interrupt, syscall.SIGTERM)
464
+
465
+ go func() {
466
+ <-c
467
+ fmt.Println("\nOperation cancelled")
468
+ os.Exit(130)
469
+ }()
470
+
471
+ cmd.Execute()
472
+ }
473
+ ```
474
+
475
+ ## Testing
476
+
477
+ ```go
478
+ package cmd
479
+
480
+ import (
481
+ "bytes"
482
+ "testing"
483
+
484
+ "github.com/spf13/cobra"
485
+ "github.com/stretchr/testify/assert"
486
+ )
487
+
488
+ func TestInitCommand(t *testing.T) {
489
+ cmd := &cobra.Command{Use: "test"}
490
+ cmd.AddCommand(initCmd)
491
+
492
+ b := bytes.NewBufferString("")
493
+ cmd.SetOut(b)
494
+ cmd.SetArgs([]string{"init", "my-project"})
495
+
496
+ err := cmd.Execute()
497
+ assert.NoError(t, err)
498
+ assert.Contains(t, b.String(), "Creating my-project")
499
+ }
500
+
501
+ func TestInitWithTemplate(t *testing.T) {
502
+ cmd := &cobra.Command{Use: "test"}
503
+ cmd.AddCommand(initCmd)
504
+
505
+ b := bytes.NewBufferString("")
506
+ cmd.SetOut(b)
507
+ cmd.SetArgs([]string{"init", "my-project", "--template", "react"})
508
+
509
+ err := cmd.Execute()
510
+ assert.NoError(t, err)
511
+ assert.Contains(t, b.String(), "react")
512
+ }
513
+ ```
514
+
515
+ ## Build & Distribution
516
+
517
+ ```makefile
518
+ # Makefile
519
+ VERSION := $(shell git describe --tags --always --dirty)
520
+ LDFLAGS := -ldflags "-X main.version=$(VERSION)"
521
+
522
+ .PHONY: build
523
+ build:
524
+ go build $(LDFLAGS) -o bin/mycli main.go
525
+
526
+ .PHONY: install
527
+ install:
528
+ go install $(LDFLAGS)
529
+
530
+ .PHONY: test
531
+ test:
532
+ go test -v ./...
533
+
534
+ .PHONY: release
535
+ release:
536
+ GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o bin/mycli-linux-amd64
537
+ GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o bin/mycli-darwin-amd64
538
+ GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o bin/mycli-darwin-arm64
539
+ GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o bin/mycli-windows-amd64.exe
540
+ ```