@oleksandr.rudnychenko/sync_loop 0.2.5 → 0.3.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.
Files changed (50) hide show
  1. package/README.md +25 -4
  2. package/bin/cli.js +3 -128
  3. package/bin/cli.ts +171 -0
  4. package/dist/bin/cli.d.ts +15 -0
  5. package/dist/bin/cli.js +137 -0
  6. package/dist/bin/cli.js.map +1 -0
  7. package/dist/src/init.d.ts +24 -0
  8. package/dist/src/init.js +404 -0
  9. package/dist/src/init.js.map +1 -0
  10. package/dist/src/server.d.ts +13 -0
  11. package/dist/src/server.js +265 -0
  12. package/dist/src/server.js.map +1 -0
  13. package/dist/src/template/.agent-loop/README.md +75 -0
  14. package/dist/src/template/.agent-loop/feedback.md +395 -0
  15. package/dist/src/template/.agent-loop/glossary.md +113 -0
  16. package/dist/src/template/.agent-loop/patterns/api-standards.md +132 -0
  17. package/dist/src/template/.agent-loop/patterns/code-patterns.md +300 -0
  18. package/dist/src/template/.agent-loop/patterns/refactoring-workflow.md +114 -0
  19. package/dist/src/template/.agent-loop/patterns/testing-guide.md +258 -0
  20. package/dist/src/template/.agent-loop/patterns.md +256 -0
  21. package/dist/src/template/.agent-loop/reasoning-kernel.md +521 -0
  22. package/dist/src/template/.agent-loop/validate-env.md +332 -0
  23. package/dist/src/template/.agent-loop/validate-n.md +321 -0
  24. package/dist/src/template/AGENTS.md +157 -0
  25. package/dist/src/template/README.md +144 -0
  26. package/dist/src/template/bootstrap-prompt.md +37 -0
  27. package/dist/src/template/protocol-summary.md +54 -0
  28. package/dist/src/template/wiring/api-standards.md +15 -0
  29. package/dist/src/template/wiring/code-patterns.md +15 -0
  30. package/dist/src/template/wiring/feedback.md +18 -0
  31. package/dist/src/template/wiring/glossary.md +11 -0
  32. package/dist/src/template/wiring/patterns.md +18 -0
  33. package/dist/src/template/wiring/reasoning-kernel.md +18 -0
  34. package/dist/src/template/wiring/refactoring-workflow.md +15 -0
  35. package/dist/src/template/wiring/testing-guide.md +15 -0
  36. package/dist/src/template/wiring/validate-env.md +17 -0
  37. package/dist/src/template/wiring/validate-n.md +17 -0
  38. package/package.json +48 -34
  39. package/src/template/wiring/api-standards.md +15 -0
  40. package/src/template/wiring/code-patterns.md +15 -0
  41. package/src/template/wiring/feedback.md +18 -0
  42. package/src/template/wiring/glossary.md +11 -0
  43. package/src/template/wiring/patterns.md +18 -0
  44. package/src/template/wiring/reasoning-kernel.md +18 -0
  45. package/src/template/wiring/refactoring-workflow.md +15 -0
  46. package/src/template/wiring/testing-guide.md +15 -0
  47. package/src/template/wiring/validate-env.md +17 -0
  48. package/src/template/wiring/validate-n.md +17 -0
  49. package/src/init.js +0 -569
  50. package/src/server.js +0 -292
package/README.md CHANGED
@@ -231,14 +231,35 @@ Use the sync_loop init tool — choose: copilot, cursor, claude, or all
231
231
 
232
232
  | Target | Files generated |
233
233
  |--------|----------------|
234
- | `copilot` | `.github/copilot-instructions.md` + `.github/instructions/*.instructions.md` |
235
- | `cursor` | `.cursor/rules/*.md` with frontmatter |
236
- | `claude` | `CLAUDE.md` + `.claude/rules/*.md` |
237
- | `all` | All of the above + `AGENTS.md` + `.agent-loop/` canonical source |
234
+ | `copilot` | `.agent-loop/` + `.github/copilot-instructions.md` + `.github/instructions/*.instructions.md` |
235
+ | `cursor` | `.agent-loop/` + `.cursor/rules/*.md` with frontmatter |
236
+ | `claude` | `.agent-loop/` + `CLAUDE.md` + `.claude/rules/*.md` |
237
+ | `all` | All of the above + `AGENTS.md` |
238
238
 
239
239
  After scaffolding, use the `bootstrap` prompt so the agent scans your codebase and populates
240
240
  the generated files with real validation commands, architecture layers, and module boundaries.
241
241
 
242
+ Platform instruction files are lightweight wrappers that delegate to `.agent-loop/*` canonical docs.
243
+
244
+ ---
245
+
246
+ ## Development
247
+
248
+ ```bash
249
+ npm install
250
+ npm run typecheck
251
+ npm test
252
+ ```
253
+
254
+ `npm test` runs a full TypeScript build first, then executes the automated test suite.
255
+
256
+ ### Publish to npm (public)
257
+
258
+ ```bash
259
+ npm run publish:public:dry-run
260
+ npm run publish:public
261
+ ```
262
+
242
263
  ---
243
264
 
244
265
  ## License
package/bin/cli.js CHANGED
@@ -1,131 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const args = process.argv.slice(2);
4
- const command = args[0];
5
-
6
- function getOptionValue(optionName) {
7
- const idx = args.indexOf(optionName);
8
- if (idx === -1) return undefined;
9
- return args[idx + 1];
10
- }
11
-
12
- function getPositionalArgs() {
13
- const positionals = [];
14
- for (let i = 1; i < args.length; i += 1) {
15
- const current = args[i];
16
- if (current === "--target") {
17
- i += 1;
18
- continue;
19
- }
20
- if (current === "--dry-run" || current === "--overwrite" || current === "--no-overwrite") {
21
- continue;
22
- }
23
- if (current.startsWith("--")) {
24
- continue;
25
- }
26
- positionals.push(current);
27
- }
28
- return positionals;
29
- }
30
-
31
- // ---------------------------------------------------------------------------
32
- // Help
33
- // ---------------------------------------------------------------------------
34
- if (args.includes("--help") || args.includes("-h")) {
35
- process.stdout.write(`
36
- sync_loop - MCP server + CLI for the SyncLoop agent reasoning protocol
37
-
38
- Usage:
39
- npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop
40
- Start MCP server (stdio transport)
41
-
42
- npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop init [projectPath] [--target <platform>] [--dry-run] [--no-overwrite]
43
- Scaffold files into the project
44
-
45
- npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop --help
46
- Show this help
47
-
48
- Init targets:
49
- copilot .github/instructions/ + copilot-instructions.md
50
- cursor .cursor/rules/ with frontmatter
51
- claude CLAUDE.md + .claude/rules/
52
- all All of the above (default)
53
-
54
- Flags:
55
- --dry-run Preview writes without modifying files
56
- --no-overwrite Do not overwrite existing generated files
57
-
58
- MCP Configuration (add to your client settings):
59
-
60
- {
61
- "mcpServers": {
62
- "sync_loop": {
63
- "command": "npx",
64
- "args": ["-y", "-p", "@oleksandr.rudnychenko/sync_loop", "sync_loop"]
65
- }
66
- }
67
- }
68
-
69
- Resources: Protocol docs on-demand (reasoning kernel, validation, feedback, patterns)
70
- Tools: init - scaffold platform-specific files
71
- Prompts: bootstrap - wire SyncLoop to your project; protocol - reasoning loop
72
-
73
- https://github.com/oleksandr-rud/SyncLoop
74
- `);
75
- process.exit(0);
76
- }
77
-
78
- // ---------------------------------------------------------------------------
79
- // CLI: npx sync_loop init
80
- // ---------------------------------------------------------------------------
81
- if (command === "init") {
82
- const target = getOptionValue("--target") ?? "all";
83
- const dryRun = args.includes("--dry-run");
84
- const overwrite = args.includes("--no-overwrite") ? false : true;
85
- const validTargets = ["copilot", "cursor", "claude", "all"];
86
-
87
- if (!validTargets.includes(target)) {
88
- process.stderr.write(`Error: unknown target "${target}". Use one of: ${validTargets.join(", ")}\n`);
89
- process.exit(1);
90
- }
91
-
92
- const [projectPath] = getPositionalArgs();
93
- const resolvedProjectPath = projectPath || process.cwd();
94
-
95
- const { init, detectStacks } = await import("../src/init.js");
96
-
97
- try {
98
- const stacks = detectStacks(resolvedProjectPath);
99
- const result = init(
100
- resolvedProjectPath,
101
- target,
102
- stacks,
103
- { dryRun, overwrite },
104
- );
105
-
106
- process.stdout.write([
107
- `SyncLoop initialized for ${target}:`,
108
- "",
109
- ...result.results,
110
- "",
111
- "Detected stacks:",
112
- ...result.stacks.map((stack) => `- ${stack.name}${stack.path ? ` (${stack.path})` : ""}: ${stack.languages.join(", ")} | ${stack.frameworks.join(", ")}`),
113
- "",
114
- dryRun
115
- ? "Dry run complete. No files were modified."
116
- : "Done. Run the bootstrap prompt to wire to your project.",
117
- "",
118
- ].join("\n"));
119
- } catch (err) {
120
- process.stderr.write(`Error: ${err.message}\n`);
121
- process.exit(1);
122
- }
123
-
124
- process.exit(0);
125
- }
126
-
127
- // ---------------------------------------------------------------------------
128
- // Default: start MCP server
129
- // ---------------------------------------------------------------------------
130
- import("../src/server.js");
3
+ import { runCli } from "../dist/bin/cli.js";
131
4
 
5
+ const exitCode = await runCli();
6
+ process.exit(exitCode);
package/bin/cli.ts ADDED
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { pathToFileURL } from "node:url";
4
+ import { detectStacks, init, type InitTarget, type StackDefinition } from "../src/init.js";
5
+ import { startServer } from "../src/server.js";
6
+
7
+ const VALID_TARGETS: InitTarget[] = ["copilot", "cursor", "claude", "all"];
8
+
9
+ const HELP_TEXT = `
10
+ sync_loop - MCP server + CLI for the SyncLoop agent reasoning protocol
11
+
12
+ Usage:
13
+ npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop
14
+ Start MCP server (stdio transport)
15
+
16
+ npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop init [projectPath] [--target <platform>] [--dry-run] [--no-overwrite]
17
+ Scaffold files into the project
18
+
19
+ npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop --help
20
+ Show this help
21
+
22
+ Init targets:
23
+ copilot .agent-loop/ + .github/instructions/ + copilot-instructions.md
24
+ cursor .agent-loop/ + .cursor/rules/ with frontmatter
25
+ claude .agent-loop/ + CLAUDE.md + .claude/rules/
26
+ all All of the above (default)
27
+
28
+ Flags:
29
+ --dry-run Preview writes without modifying files
30
+ --no-overwrite Do not overwrite existing generated files
31
+
32
+ MCP Configuration (add to your client settings):
33
+
34
+ {
35
+ "mcpServers": {
36
+ "sync_loop": {
37
+ "command": "npx",
38
+ "args": ["-y", "-p", "@oleksandr.rudnychenko/sync_loop", "sync_loop"]
39
+ }
40
+ }
41
+ }
42
+
43
+ Resources: Protocol docs on-demand (reasoning kernel, validation, feedback, patterns)
44
+ Tools: init - scaffold platform-specific files
45
+ Prompts: bootstrap - wire SyncLoop to your project; protocol - reasoning loop
46
+
47
+ https://github.com/oleksandr-rud/SyncLoop
48
+ `;
49
+
50
+ export interface CliIo {
51
+ stdout: Pick<NodeJS.WritableStream, "write">;
52
+ stderr: Pick<NodeJS.WritableStream, "write">;
53
+ cwd: () => string;
54
+ }
55
+
56
+ export interface CliDeps {
57
+ detectStacksFn: (projectPath: string) => StackDefinition[];
58
+ initFn: typeof init;
59
+ startServerFn: () => Promise<unknown>;
60
+ }
61
+
62
+ function defaultIo(): CliIo {
63
+ return {
64
+ stdout: process.stdout,
65
+ stderr: process.stderr,
66
+ cwd: () => process.cwd(),
67
+ };
68
+ }
69
+
70
+ function defaultDeps(): CliDeps {
71
+ return {
72
+ detectStacksFn: detectStacks,
73
+ initFn: init,
74
+ startServerFn: startServer,
75
+ };
76
+ }
77
+
78
+ export function getOptionValue(args: string[], optionName: string): string | undefined {
79
+ const idx = args.indexOf(optionName);
80
+ if (idx === -1) return undefined;
81
+ return args[idx + 1];
82
+ }
83
+
84
+ export function getPositionalArgs(args: string[]): string[] {
85
+ const positionals: string[] = [];
86
+ for (let i = 1; i < args.length; i += 1) {
87
+ const current = args[i];
88
+ if (current === "--target") {
89
+ i += 1;
90
+ continue;
91
+ }
92
+ if (current === "--dry-run" || current === "--overwrite" || current === "--no-overwrite") {
93
+ continue;
94
+ }
95
+ if (current.startsWith("--")) {
96
+ continue;
97
+ }
98
+ positionals.push(current);
99
+ }
100
+ return positionals;
101
+ }
102
+
103
+ export async function runCli(
104
+ args: string[] = process.argv.slice(2),
105
+ io: CliIo = defaultIo(),
106
+ deps: CliDeps = defaultDeps(),
107
+ ): Promise<number> {
108
+ const command = args[0];
109
+
110
+ if (args.includes("--help") || args.includes("-h")) {
111
+ io.stdout.write(HELP_TEXT);
112
+ return 0;
113
+ }
114
+
115
+ if (command === "init") {
116
+ const target = (getOptionValue(args, "--target") ?? "all") as InitTarget;
117
+ const dryRun = args.includes("--dry-run");
118
+ const overwrite = args.includes("--no-overwrite") ? false : true;
119
+
120
+ if (!VALID_TARGETS.includes(target)) {
121
+ io.stderr.write(`Error: unknown target "${target}". Use one of: ${VALID_TARGETS.join(", ")}\n`);
122
+ return 1;
123
+ }
124
+
125
+ const [projectPath] = getPositionalArgs(args);
126
+ const resolvedProjectPath = projectPath || io.cwd();
127
+
128
+ try {
129
+ const stacks = deps.detectStacksFn(resolvedProjectPath);
130
+ const result = deps.initFn(
131
+ resolvedProjectPath,
132
+ target,
133
+ stacks,
134
+ { dryRun, overwrite },
135
+ );
136
+
137
+ io.stdout.write([
138
+ `SyncLoop initialized for ${target}:`,
139
+ "",
140
+ ...result.results,
141
+ "",
142
+ "Detected stacks:",
143
+ ...result.stacks.map((stack) => `- ${stack.name}${stack.path ? ` (${stack.path})` : ""}: ${stack.languages.join(", ")} | ${stack.frameworks.join(", ")}`),
144
+ "",
145
+ dryRun
146
+ ? "Dry run complete. No files were modified."
147
+ : "Done. Run the bootstrap prompt to wire to your project.",
148
+ "",
149
+ ].join("\n"));
150
+ return 0;
151
+ } catch (err) {
152
+ const message = err instanceof Error ? err.message : String(err);
153
+ io.stderr.write(`Error: ${message}\n`);
154
+ return 1;
155
+ }
156
+ }
157
+
158
+ await deps.startServerFn();
159
+ return 0;
160
+ }
161
+
162
+ function isMainModule(metaUrl: string): boolean {
163
+ const entryFile = process.argv[1];
164
+ if (!entryFile) return false;
165
+ return metaUrl === pathToFileURL(entryFile).href;
166
+ }
167
+
168
+ if (isMainModule(import.meta.url)) {
169
+ const exitCode = await runCli();
170
+ process.exit(exitCode);
171
+ }
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { init, type StackDefinition } from "../src/init.js";
3
+ export interface CliIo {
4
+ stdout: Pick<NodeJS.WritableStream, "write">;
5
+ stderr: Pick<NodeJS.WritableStream, "write">;
6
+ cwd: () => string;
7
+ }
8
+ export interface CliDeps {
9
+ detectStacksFn: (projectPath: string) => StackDefinition[];
10
+ initFn: typeof init;
11
+ startServerFn: () => Promise<unknown>;
12
+ }
13
+ export declare function getOptionValue(args: string[], optionName: string): string | undefined;
14
+ export declare function getPositionalArgs(args: string[]): string[];
15
+ export declare function runCli(args?: string[], io?: CliIo, deps?: CliDeps): Promise<number>;
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+ import { pathToFileURL } from "node:url";
3
+ import { detectStacks, init } from "../src/init.js";
4
+ import { startServer } from "../src/server.js";
5
+ const VALID_TARGETS = ["copilot", "cursor", "claude", "all"];
6
+ const HELP_TEXT = `
7
+ sync_loop - MCP server + CLI for the SyncLoop agent reasoning protocol
8
+
9
+ Usage:
10
+ npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop
11
+ Start MCP server (stdio transport)
12
+
13
+ npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop init [projectPath] [--target <platform>] [--dry-run] [--no-overwrite]
14
+ Scaffold files into the project
15
+
16
+ npx -y -p @oleksandr.rudnychenko/sync_loop sync_loop --help
17
+ Show this help
18
+
19
+ Init targets:
20
+ copilot .agent-loop/ + .github/instructions/ + copilot-instructions.md
21
+ cursor .agent-loop/ + .cursor/rules/ with frontmatter
22
+ claude .agent-loop/ + CLAUDE.md + .claude/rules/
23
+ all All of the above (default)
24
+
25
+ Flags:
26
+ --dry-run Preview writes without modifying files
27
+ --no-overwrite Do not overwrite existing generated files
28
+
29
+ MCP Configuration (add to your client settings):
30
+
31
+ {
32
+ "mcpServers": {
33
+ "sync_loop": {
34
+ "command": "npx",
35
+ "args": ["-y", "-p", "@oleksandr.rudnychenko/sync_loop", "sync_loop"]
36
+ }
37
+ }
38
+ }
39
+
40
+ Resources: Protocol docs on-demand (reasoning kernel, validation, feedback, patterns)
41
+ Tools: init - scaffold platform-specific files
42
+ Prompts: bootstrap - wire SyncLoop to your project; protocol - reasoning loop
43
+
44
+ https://github.com/oleksandr-rud/SyncLoop
45
+ `;
46
+ function defaultIo() {
47
+ return {
48
+ stdout: process.stdout,
49
+ stderr: process.stderr,
50
+ cwd: () => process.cwd(),
51
+ };
52
+ }
53
+ function defaultDeps() {
54
+ return {
55
+ detectStacksFn: detectStacks,
56
+ initFn: init,
57
+ startServerFn: startServer,
58
+ };
59
+ }
60
+ export function getOptionValue(args, optionName) {
61
+ const idx = args.indexOf(optionName);
62
+ if (idx === -1)
63
+ return undefined;
64
+ return args[idx + 1];
65
+ }
66
+ export function getPositionalArgs(args) {
67
+ const positionals = [];
68
+ for (let i = 1; i < args.length; i += 1) {
69
+ const current = args[i];
70
+ if (current === "--target") {
71
+ i += 1;
72
+ continue;
73
+ }
74
+ if (current === "--dry-run" || current === "--overwrite" || current === "--no-overwrite") {
75
+ continue;
76
+ }
77
+ if (current.startsWith("--")) {
78
+ continue;
79
+ }
80
+ positionals.push(current);
81
+ }
82
+ return positionals;
83
+ }
84
+ export async function runCli(args = process.argv.slice(2), io = defaultIo(), deps = defaultDeps()) {
85
+ const command = args[0];
86
+ if (args.includes("--help") || args.includes("-h")) {
87
+ io.stdout.write(HELP_TEXT);
88
+ return 0;
89
+ }
90
+ if (command === "init") {
91
+ const target = (getOptionValue(args, "--target") ?? "all");
92
+ const dryRun = args.includes("--dry-run");
93
+ const overwrite = args.includes("--no-overwrite") ? false : true;
94
+ if (!VALID_TARGETS.includes(target)) {
95
+ io.stderr.write(`Error: unknown target "${target}". Use one of: ${VALID_TARGETS.join(", ")}\n`);
96
+ return 1;
97
+ }
98
+ const [projectPath] = getPositionalArgs(args);
99
+ const resolvedProjectPath = projectPath || io.cwd();
100
+ try {
101
+ const stacks = deps.detectStacksFn(resolvedProjectPath);
102
+ const result = deps.initFn(resolvedProjectPath, target, stacks, { dryRun, overwrite });
103
+ io.stdout.write([
104
+ `SyncLoop initialized for ${target}:`,
105
+ "",
106
+ ...result.results,
107
+ "",
108
+ "Detected stacks:",
109
+ ...result.stacks.map((stack) => `- ${stack.name}${stack.path ? ` (${stack.path})` : ""}: ${stack.languages.join(", ")} | ${stack.frameworks.join(", ")}`),
110
+ "",
111
+ dryRun
112
+ ? "Dry run complete. No files were modified."
113
+ : "Done. Run the bootstrap prompt to wire to your project.",
114
+ "",
115
+ ].join("\n"));
116
+ return 0;
117
+ }
118
+ catch (err) {
119
+ const message = err instanceof Error ? err.message : String(err);
120
+ io.stderr.write(`Error: ${message}\n`);
121
+ return 1;
122
+ }
123
+ }
124
+ await deps.startServerFn();
125
+ return 0;
126
+ }
127
+ function isMainModule(metaUrl) {
128
+ const entryFile = process.argv[1];
129
+ if (!entryFile)
130
+ return false;
131
+ return metaUrl === pathToFileURL(entryFile).href;
132
+ }
133
+ if (isMainModule(import.meta.url)) {
134
+ const exitCode = await runCli();
135
+ process.exit(exitCode);
136
+ }
137
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export type InitTarget = "copilot" | "cursor" | "claude" | "all";
2
+ export interface StackDefinition {
3
+ name: string;
4
+ languages: string[];
5
+ frameworks: string[];
6
+ testRunner?: string;
7
+ typeChecker?: string;
8
+ linter?: string;
9
+ packageManager?: string;
10
+ path?: string;
11
+ }
12
+ export interface InitOptions {
13
+ dryRun?: boolean;
14
+ overwrite?: boolean;
15
+ }
16
+ export declare function detectStacks(projectPath: string): StackDefinition[];
17
+ export declare function init(projectPath: string, target?: InitTarget, stacks?: StackDefinition[], options?: InitOptions): {
18
+ projectPath: string;
19
+ target: InitTarget;
20
+ dryRun: boolean;
21
+ overwrite: boolean;
22
+ stacks: StackDefinition[];
23
+ results: string[];
24
+ };