mobius-loop 1.0.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.
Files changed (72) hide show
  1. package/.claude/commands/linear/define.md +22 -0
  2. package/.claude/commands/linear/execute.md +22 -0
  3. package/.claude/commands/linear/refine.md +22 -0
  4. package/.claude/commands/linear/verify.md +22 -0
  5. package/.claude/skills/define-linear-issue/SKILL.md +386 -0
  6. package/.claude/skills/execute-linear-issue/SKILL.md +629 -0
  7. package/.claude/skills/refine-linear-issue/SKILL.md +379 -0
  8. package/.claude/skills/verify-linear-issue/SKILL.md +663 -0
  9. package/AGENTS.md +70 -0
  10. package/LICENSE +21 -0
  11. package/README.md +457 -0
  12. package/dist/bin/mobius.d.ts +3 -0
  13. package/dist/bin/mobius.d.ts.map +1 -0
  14. package/dist/bin/mobius.js +75 -0
  15. package/dist/bin/mobius.js.map +1 -0
  16. package/dist/commands/config.d.ts +6 -0
  17. package/dist/commands/config.d.ts.map +1 -0
  18. package/dist/commands/config.js +88 -0
  19. package/dist/commands/config.js.map +1 -0
  20. package/dist/commands/doctor.d.ts +2 -0
  21. package/dist/commands/doctor.d.ts.map +1 -0
  22. package/dist/commands/doctor.js +86 -0
  23. package/dist/commands/doctor.js.map +1 -0
  24. package/dist/commands/run.d.ts +10 -0
  25. package/dist/commands/run.d.ts.map +1 -0
  26. package/dist/commands/run.js +62 -0
  27. package/dist/commands/run.js.map +1 -0
  28. package/dist/commands/setup.d.ts +2 -0
  29. package/dist/commands/setup.d.ts.map +1 -0
  30. package/dist/commands/setup.js +131 -0
  31. package/dist/commands/setup.js.map +1 -0
  32. package/dist/lib/checks/cclean.d.ts +3 -0
  33. package/dist/lib/checks/cclean.d.ts.map +1 -0
  34. package/dist/lib/checks/cclean.js +23 -0
  35. package/dist/lib/checks/cclean.js.map +1 -0
  36. package/dist/lib/checks/claude.d.ts +3 -0
  37. package/dist/lib/checks/claude.d.ts.map +1 -0
  38. package/dist/lib/checks/claude.js +38 -0
  39. package/dist/lib/checks/claude.js.map +1 -0
  40. package/dist/lib/checks/config.d.ts +4 -0
  41. package/dist/lib/checks/config.d.ts.map +1 -0
  42. package/dist/lib/checks/config.js +45 -0
  43. package/dist/lib/checks/config.js.map +1 -0
  44. package/dist/lib/checks/docker.d.ts +3 -0
  45. package/dist/lib/checks/docker.d.ts.map +1 -0
  46. package/dist/lib/checks/docker.js +46 -0
  47. package/dist/lib/checks/docker.js.map +1 -0
  48. package/dist/lib/checks/linear-mcp.d.ts +3 -0
  49. package/dist/lib/checks/linear-mcp.d.ts.map +1 -0
  50. package/dist/lib/checks/linear-mcp.js +46 -0
  51. package/dist/lib/checks/linear-mcp.js.map +1 -0
  52. package/dist/lib/checks/path.d.ts +5 -0
  53. package/dist/lib/checks/path.d.ts.map +1 -0
  54. package/dist/lib/checks/path.js +49 -0
  55. package/dist/lib/checks/path.js.map +1 -0
  56. package/dist/lib/config.d.ts +37 -0
  57. package/dist/lib/config.d.ts.map +1 -0
  58. package/dist/lib/config.js +145 -0
  59. package/dist/lib/config.js.map +1 -0
  60. package/dist/lib/paths.d.ts +39 -0
  61. package/dist/lib/paths.d.ts.map +1 -0
  62. package/dist/lib/paths.js +117 -0
  63. package/dist/lib/paths.js.map +1 -0
  64. package/dist/types.d.ts +39 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/types.js +19 -0
  67. package/dist/types.js.map +1 -0
  68. package/mobius.config.yaml +38 -0
  69. package/package.json +56 -0
  70. package/scripts/mobius.sh +394 -0
  71. package/scripts/render-diagrams.sh +38 -0
  72. package/scripts/render-terminal.sh +49 -0
@@ -0,0 +1,3 @@
1
+ import type { CheckResult, Backend } from '../../types.js';
2
+ export declare function checkLinearMcp(backend: Backend): Promise<CheckResult>;
3
+ //# sourceMappingURL=linear-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-mcp.d.ts","sourceRoot":"","sources":["../../../src/lib/checks/linear-mcp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE3D,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CA8C3E"}
@@ -0,0 +1,46 @@
1
+ import { execa } from 'execa';
2
+ export async function checkLinearMcp(backend) {
3
+ const name = 'Linear MCP';
4
+ if (backend !== 'linear') {
5
+ return {
6
+ name,
7
+ status: 'skip',
8
+ message: `Not needed (using ${backend} backend)`,
9
+ required: false,
10
+ };
11
+ }
12
+ // Try to check if Claude can access Linear MCP tools
13
+ // This is a lightweight check - we can't fully verify without running Claude
14
+ try {
15
+ // Check if claude has MCP configured by looking at settings
16
+ const { stdout } = await execa('claude', ['mcp', 'list'], {
17
+ timeout: 10000,
18
+ reject: false,
19
+ });
20
+ if (stdout.toLowerCase().includes('linear')) {
21
+ return {
22
+ name,
23
+ status: 'pass',
24
+ message: 'Linear MCP tools available',
25
+ required: false,
26
+ };
27
+ }
28
+ return {
29
+ name,
30
+ status: 'warn',
31
+ message: 'Linear MCP not detected in Claude config',
32
+ required: false,
33
+ details: 'Linear MCP may be configured at project level. Run a test task to verify.',
34
+ };
35
+ }
36
+ catch {
37
+ return {
38
+ name,
39
+ status: 'warn',
40
+ message: 'Could not verify Linear MCP status',
41
+ required: false,
42
+ details: 'Linear MCP may still work - run a test task to verify',
43
+ };
44
+ }
45
+ }
46
+ //# sourceMappingURL=linear-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-mcp.js","sourceRoot":"","sources":["../../../src/lib/checks/linear-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB;IACnD,MAAM,IAAI,GAAG,YAAY,CAAC;IAE1B,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,qBAAqB,OAAO,WAAW;YAChD,QAAQ,EAAE,KAAK;SAChB,CAAC;IACJ,CAAC;IAED,qDAAqD;IACrD,6EAA6E;IAC7E,IAAI,CAAC;QACH,4DAA4D;QAC5D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;YACxD,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5C,OAAO;gBACL,IAAI;gBACJ,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,4BAA4B;gBACrC,QAAQ,EAAE,KAAK;aAChB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,0CAA0C;YACnD,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,2EAA2E;SACrF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,oCAAoC;YAC7C,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,uDAAuD;SACjE,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { CheckResult } from '../../types.js';
2
+ import type { PathConfig } from '../../types.js';
3
+ export declare function checkPath(paths: PathConfig): Promise<CheckResult>;
4
+ export declare function checkSkills(paths: PathConfig): Promise<CheckResult>;
5
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/lib/checks/path.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAsB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBvE;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA+BzE"}
@@ -0,0 +1,49 @@
1
+ import { existsSync } from 'node:fs';
2
+ export async function checkPath(paths) {
3
+ const name = 'Script path';
4
+ if (!existsSync(paths.scriptPath)) {
5
+ return {
6
+ name,
7
+ status: 'fail',
8
+ message: 'issue-loop.sh script not found',
9
+ required: true,
10
+ details: `Expected at: ${paths.scriptPath}`,
11
+ };
12
+ }
13
+ return {
14
+ name,
15
+ status: 'pass',
16
+ message: `Found at ${paths.scriptPath}`,
17
+ required: true,
18
+ };
19
+ }
20
+ export async function checkSkills(paths) {
21
+ const name = 'Skills';
22
+ if (!existsSync(paths.skillsPath)) {
23
+ return {
24
+ name,
25
+ status: 'fail',
26
+ message: `Skills directory not found at ${paths.skillsPath}`,
27
+ required: true,
28
+ details: "Run 'loop setup' to install skills",
29
+ };
30
+ }
31
+ // Check for Linear skills specifically
32
+ const executeSkill = `${paths.skillsPath}/execute-linear-issue`;
33
+ if (!existsSync(executeSkill)) {
34
+ return {
35
+ name,
36
+ status: 'warn',
37
+ message: 'Linear execute skill not found',
38
+ required: false,
39
+ details: "Run 'loop setup' to install skills",
40
+ };
41
+ }
42
+ return {
43
+ name,
44
+ status: 'pass',
45
+ message: `Installed at ${paths.skillsPath}`,
46
+ required: true,
47
+ };
48
+ }
49
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.js","sourceRoot":"","sources":["../../../src/lib/checks/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIrC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAiB;IAC/C,MAAM,IAAI,GAAG,aAAa,CAAC;IAE3B,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gCAAgC;YACzC,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,gBAAgB,KAAK,CAAC,UAAU,EAAE;SAC5C,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,YAAY,KAAK,CAAC,UAAU,EAAE;QACvC,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAiB;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC;IAEtB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,iCAAiC,KAAK,CAAC,UAAU,EAAE;YAC5D,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,oCAAoC;SAC9C,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,MAAM,YAAY,GAAG,GAAG,KAAK,CAAC,UAAU,uBAAuB,CAAC;IAChE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,gCAAgC;YACzC,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,oCAAoC;SAC9C,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,gBAAgB,KAAK,CAAC,UAAU,EAAE;QAC3C,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { LoopConfig, PathConfig } from '../types.js';
2
+ /**
3
+ * Read and parse config file, merging with defaults
4
+ */
5
+ export declare function readConfig(configPath: string): LoopConfig;
6
+ /**
7
+ * Write config to file
8
+ */
9
+ export declare function writeConfig(configPath: string, config: LoopConfig): void;
10
+ /**
11
+ * Copy skills from package to target directory
12
+ */
13
+ export declare function copySkills(targetDir: string): void;
14
+ /**
15
+ * Copy commands from package to target directory
16
+ */
17
+ export declare function copyCommands(paths: PathConfig): void;
18
+ /**
19
+ * Copy AGENTS.md template to project
20
+ */
21
+ export declare function copyAgentsTemplate(targetDir: string): void;
22
+ /**
23
+ * Copy default config as template
24
+ */
25
+ export declare function copyDefaultConfig(targetPath: string): void;
26
+ /**
27
+ * Check if config exists
28
+ */
29
+ export declare function configExists(configPath: string): boolean;
30
+ /**
31
+ * Validate config structure
32
+ */
33
+ export declare function validateConfig(config: LoopConfig): {
34
+ valid: boolean;
35
+ errors: string[];
36
+ };
37
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAU1D;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAsBzD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAexE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAalD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAkBpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAa1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAgB1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA2BvF"}
@@ -0,0 +1,145 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, cpSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { parse, stringify } from 'yaml';
4
+ import { DEFAULT_CONFIG } from '../types.js';
5
+ import { getBundledSkillsDir, getBundledCommandsDir, getDefaultConfigPath, getAgentsTemplatePath, getGlobalCommandsDir, } from './paths.js';
6
+ /**
7
+ * Read and parse config file, merging with defaults
8
+ */
9
+ export function readConfig(configPath) {
10
+ if (!existsSync(configPath)) {
11
+ return { ...DEFAULT_CONFIG };
12
+ }
13
+ try {
14
+ const content = readFileSync(configPath, 'utf-8');
15
+ const parsed = parse(content);
16
+ // Deep merge with defaults
17
+ return {
18
+ backend: parsed.backend ?? DEFAULT_CONFIG.backend,
19
+ linear: parsed.linear,
20
+ jira: parsed.jira,
21
+ execution: {
22
+ ...DEFAULT_CONFIG.execution,
23
+ ...parsed.execution,
24
+ },
25
+ };
26
+ }
27
+ catch {
28
+ return { ...DEFAULT_CONFIG };
29
+ }
30
+ }
31
+ /**
32
+ * Write config to file
33
+ */
34
+ export function writeConfig(configPath, config) {
35
+ const dir = dirname(configPath);
36
+ if (!existsSync(dir)) {
37
+ mkdirSync(dir, { recursive: true });
38
+ }
39
+ const content = `# Loop Configuration
40
+ # Generated by 'loop setup'
41
+ #
42
+ # Environment variables override these settings:
43
+ # ISSUE_LOOP_BACKEND, ISSUE_LOOP_DELAY_SECONDS, etc.
44
+
45
+ ${stringify(config)}`;
46
+ writeFileSync(configPath, content, 'utf-8');
47
+ }
48
+ /**
49
+ * Copy skills from package to target directory
50
+ */
51
+ export function copySkills(targetDir) {
52
+ const bundledDir = getBundledSkillsDir();
53
+ if (!existsSync(bundledDir)) {
54
+ throw new Error(`Bundled skills not found at ${bundledDir}`);
55
+ }
56
+ if (!existsSync(targetDir)) {
57
+ mkdirSync(targetDir, { recursive: true });
58
+ }
59
+ // Copy each skill directory
60
+ cpSync(bundledDir, targetDir, { recursive: true });
61
+ }
62
+ /**
63
+ * Copy commands from package to target directory
64
+ */
65
+ export function copyCommands(paths) {
66
+ const bundledDir = getBundledCommandsDir();
67
+ if (!existsSync(bundledDir)) {
68
+ // Commands are optional
69
+ return;
70
+ }
71
+ const targetDir = paths.type === 'local'
72
+ ? join(dirname(paths.configPath), '.claude', 'commands')
73
+ : getGlobalCommandsDir();
74
+ if (!existsSync(targetDir)) {
75
+ mkdirSync(targetDir, { recursive: true });
76
+ }
77
+ cpSync(bundledDir, targetDir, { recursive: true });
78
+ }
79
+ /**
80
+ * Copy AGENTS.md template to project
81
+ */
82
+ export function copyAgentsTemplate(targetDir) {
83
+ const templatePath = getAgentsTemplatePath();
84
+ const targetPath = join(targetDir, 'AGENTS.md');
85
+ if (!existsSync(templatePath)) {
86
+ return;
87
+ }
88
+ // Only copy if target doesn't exist
89
+ if (!existsSync(targetPath)) {
90
+ const content = readFileSync(templatePath, 'utf-8');
91
+ writeFileSync(targetPath, content, 'utf-8');
92
+ }
93
+ }
94
+ /**
95
+ * Copy default config as template
96
+ */
97
+ export function copyDefaultConfig(targetPath) {
98
+ const defaultPath = getDefaultConfigPath();
99
+ if (!existsSync(defaultPath)) {
100
+ // Create from DEFAULT_CONFIG if template missing
101
+ writeConfig(targetPath, DEFAULT_CONFIG);
102
+ return;
103
+ }
104
+ const dir = dirname(targetPath);
105
+ if (!existsSync(dir)) {
106
+ mkdirSync(dir, { recursive: true });
107
+ }
108
+ const content = readFileSync(defaultPath, 'utf-8');
109
+ writeFileSync(targetPath, content, 'utf-8');
110
+ }
111
+ /**
112
+ * Check if config exists
113
+ */
114
+ export function configExists(configPath) {
115
+ return existsSync(configPath);
116
+ }
117
+ /**
118
+ * Validate config structure
119
+ */
120
+ export function validateConfig(config) {
121
+ const errors = [];
122
+ if (!config.backend) {
123
+ errors.push('Missing required field: backend');
124
+ }
125
+ else if (!['linear', 'jira'].includes(config.backend)) {
126
+ errors.push(`Invalid backend: ${config.backend}. Must be 'linear' or 'jira'`);
127
+ }
128
+ if (!config.execution) {
129
+ errors.push('Missing required section: execution');
130
+ }
131
+ else {
132
+ if (typeof config.execution.delay_seconds !== 'number' || config.execution.delay_seconds < 0) {
133
+ errors.push('execution.delay_seconds must be a non-negative number');
134
+ }
135
+ if (typeof config.execution.max_iterations !== 'number' ||
136
+ config.execution.max_iterations < 0) {
137
+ errors.push('execution.max_iterations must be a non-negative number');
138
+ }
139
+ if (!['opus', 'sonnet', 'haiku'].includes(config.execution.model)) {
140
+ errors.push(`Invalid model: ${config.execution.model}. Must be 'opus', 'sonnet', or 'haiku'`);
141
+ }
142
+ }
143
+ return { valid: errors.length === 0, errors };
144
+ }
145
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { PathConfig } from '../types.js';
2
+ /** Package root directory (where package.json lives) */
3
+ export declare function getPackageRoot(): string;
4
+ /** Global config directory (~/.config/mobius) */
5
+ export declare function getGlobalConfigDir(): string;
6
+ /** Global skills directory (~/.claude/skills) */
7
+ export declare function getGlobalSkillsDir(): string;
8
+ /** Global commands directory (~/.claude/commands) */
9
+ export declare function getGlobalCommandsDir(): string;
10
+ /**
11
+ * Walk up from startDir looking for mobius.config.yaml
12
+ */
13
+ export declare function findLocalConfig(startDir?: string): string | null;
14
+ /**
15
+ * Resolve paths for local or global installation
16
+ * Priority: local config (walk up tree) > global config
17
+ */
18
+ export declare function resolvePaths(): PathConfig;
19
+ /**
20
+ * Get paths for a specific installation type (used by setup)
21
+ */
22
+ export declare function getPathsForType(type: 'local' | 'global', projectDir?: string): PathConfig;
23
+ /**
24
+ * Get bundled skills directory from package
25
+ */
26
+ export declare function getBundledSkillsDir(): string;
27
+ /**
28
+ * Get bundled commands directory from package
29
+ */
30
+ export declare function getBundledCommandsDir(): string;
31
+ /**
32
+ * Get default config template path
33
+ */
34
+ export declare function getDefaultConfigPath(): string;
35
+ /**
36
+ * Get AGENTS.md template path
37
+ */
38
+ export declare function getAgentsTemplatePath(): string;
39
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,wDAAwD;AACxD,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAG3C;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,qDAAqD;AACrD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAmB/E;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,UAAU,CAuBzC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,UAAU,CAoBzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}
@@ -0,0 +1,117 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { fileURLToPath } from 'node:url';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ /** Package root directory (where package.json lives) */
8
+ export function getPackageRoot() {
9
+ // In dist/lib/paths.js, go up two levels to package root
10
+ return resolve(__dirname, '..', '..');
11
+ }
12
+ /** Global config directory (~/.config/mobius) */
13
+ export function getGlobalConfigDir() {
14
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
15
+ return join(xdgConfig, 'mobius');
16
+ }
17
+ /** Global skills directory (~/.claude/skills) */
18
+ export function getGlobalSkillsDir() {
19
+ return join(homedir(), '.claude', 'skills');
20
+ }
21
+ /** Global commands directory (~/.claude/commands) */
22
+ export function getGlobalCommandsDir() {
23
+ return join(homedir(), '.claude', 'commands');
24
+ }
25
+ /**
26
+ * Walk up from startDir looking for mobius.config.yaml
27
+ */
28
+ export function findLocalConfig(startDir = process.cwd()) {
29
+ let dir = resolve(startDir);
30
+ const root = dirname(dir);
31
+ while (dir !== root) {
32
+ const configPath = join(dir, 'mobius.config.yaml');
33
+ if (existsSync(configPath)) {
34
+ return configPath;
35
+ }
36
+ dir = dirname(dir);
37
+ }
38
+ // Check root as well
39
+ const rootConfig = join(root, 'mobius.config.yaml');
40
+ if (existsSync(rootConfig)) {
41
+ return rootConfig;
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Resolve paths for local or global installation
47
+ * Priority: local config (walk up tree) > global config
48
+ */
49
+ export function resolvePaths() {
50
+ const packageRoot = getPackageRoot();
51
+ // Check for local config first
52
+ const localConfig = findLocalConfig();
53
+ if (localConfig) {
54
+ const projectRoot = dirname(localConfig);
55
+ return {
56
+ type: 'local',
57
+ configPath: localConfig,
58
+ skillsPath: join(projectRoot, '.claude', 'skills'),
59
+ scriptPath: join(packageRoot, 'scripts', 'mobius.sh'),
60
+ };
61
+ }
62
+ // Fall back to global config
63
+ const globalConfigDir = getGlobalConfigDir();
64
+ return {
65
+ type: 'global',
66
+ configPath: join(globalConfigDir, 'config.yaml'),
67
+ skillsPath: getGlobalSkillsDir(),
68
+ scriptPath: join(packageRoot, 'scripts', 'mobius.sh'),
69
+ };
70
+ }
71
+ /**
72
+ * Get paths for a specific installation type (used by setup)
73
+ */
74
+ export function getPathsForType(type, projectDir) {
75
+ const packageRoot = getPackageRoot();
76
+ if (type === 'local') {
77
+ const dir = projectDir || process.cwd();
78
+ return {
79
+ type: 'local',
80
+ configPath: join(dir, 'mobius.config.yaml'),
81
+ skillsPath: join(dir, '.claude', 'skills'),
82
+ scriptPath: join(packageRoot, 'scripts', 'mobius.sh'),
83
+ };
84
+ }
85
+ const globalConfigDir = getGlobalConfigDir();
86
+ return {
87
+ type: 'global',
88
+ configPath: join(globalConfigDir, 'config.yaml'),
89
+ skillsPath: getGlobalSkillsDir(),
90
+ scriptPath: join(packageRoot, 'scripts', 'mobius.sh'),
91
+ };
92
+ }
93
+ /**
94
+ * Get bundled skills directory from package
95
+ */
96
+ export function getBundledSkillsDir() {
97
+ return join(getPackageRoot(), '.claude', 'skills');
98
+ }
99
+ /**
100
+ * Get bundled commands directory from package
101
+ */
102
+ export function getBundledCommandsDir() {
103
+ return join(getPackageRoot(), '.claude', 'commands');
104
+ }
105
+ /**
106
+ * Get default config template path
107
+ */
108
+ export function getDefaultConfigPath() {
109
+ return join(getPackageRoot(), 'mobius.config.yaml');
110
+ }
111
+ /**
112
+ * Get AGENTS.md template path
113
+ */
114
+ export function getAgentsTemplatePath() {
115
+ return join(getPackageRoot(), 'AGENTS.md');
116
+ }
117
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export type Backend = 'linear' | 'jira';
2
+ export type Model = 'opus' | 'sonnet' | 'haiku';
3
+ export interface ExecutionConfig {
4
+ delay_seconds: number;
5
+ max_iterations: number;
6
+ model: Model;
7
+ sandbox: boolean;
8
+ container_name: string;
9
+ }
10
+ export interface LinearConfig {
11
+ }
12
+ export interface JiraConfig {
13
+ base_url?: string;
14
+ project_key?: string;
15
+ auth_method?: 'api_token' | 'oauth';
16
+ }
17
+ export interface LoopConfig {
18
+ backend: Backend;
19
+ linear?: LinearConfig;
20
+ jira?: JiraConfig;
21
+ execution: ExecutionConfig;
22
+ }
23
+ export interface CheckResult {
24
+ name: string;
25
+ status: 'pass' | 'fail' | 'warn' | 'skip';
26
+ message: string;
27
+ required: boolean;
28
+ details?: string;
29
+ }
30
+ export interface PathConfig {
31
+ type: 'local' | 'global';
32
+ configPath: string;
33
+ skillsPath: string;
34
+ scriptPath: string;
35
+ }
36
+ export declare const DEFAULT_CONFIG: LoopConfig;
37
+ export declare const BACKEND_SKILLS: Record<Backend, string>;
38
+ export declare const BACKEND_ID_PATTERNS: Record<Backend, RegExp>;
39
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AACxC,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;CAE5B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,cAAc,EAAE,UAS5B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAGlD,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAGvD,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,19 @@
1
+ export const DEFAULT_CONFIG = {
2
+ backend: 'linear',
3
+ execution: {
4
+ delay_seconds: 3,
5
+ max_iterations: 50,
6
+ model: 'opus',
7
+ sandbox: true,
8
+ container_name: 'mobius-sandbox',
9
+ },
10
+ };
11
+ export const BACKEND_SKILLS = {
12
+ linear: '/execute-linear-issue',
13
+ jira: '/execute-jira-issue',
14
+ };
15
+ export const BACKEND_ID_PATTERNS = {
16
+ linear: /^[A-Z]+-[0-9]+$/,
17
+ jira: /^[A-Z]+-[0-9]+$/,
18
+ };
19
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA2CA,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC,OAAO,EAAE,QAAQ;IACjB,SAAS,EAAE;QACT,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,EAAE;QAClB,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,IAAI;QACb,cAAc,EAAE,gBAAgB;KACjC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,MAAM,EAAE,uBAAuB;IAC/B,IAAI,EAAE,qBAAqB;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAA4B;IAC1D,MAAM,EAAE,iBAAiB;IACzB,IAAI,EAAE,iBAAiB;CACxB,CAAC"}
@@ -0,0 +1,38 @@
1
+ # Mobius Configuration
2
+ # Copy to ~/.config/mobius/config.yaml and customize
3
+ #
4
+ # Environment variables override these settings:
5
+ # MOBIUS_BACKEND, MOBIUS_DELAY_SECONDS, etc.
6
+
7
+ # Issue tracker backend: linear | jira
8
+ backend: linear
9
+
10
+ # Backend-specific settings
11
+ linear:
12
+ # Uses Linear MCP tools (auto-configured via Claude Code)
13
+ # No additional configuration required
14
+
15
+ jira:
16
+ # Future Jira integration
17
+ # Uncomment and configure when using Jira backend:
18
+ # base_url: https://yourcompany.atlassian.net
19
+ # project_key: PROJ
20
+ # auth_method: api_token # api_token | oauth
21
+
22
+ # Execution settings
23
+ execution:
24
+ # Seconds to wait between loop iterations
25
+ delay_seconds: 3
26
+
27
+ # Maximum iterations (0 = unlimited)
28
+ max_iterations: 50
29
+
30
+ # Claude model to use: opus | sonnet | haiku
31
+ model: opus
32
+
33
+ # Run in Docker sandbox by default (safer for autonomous execution)
34
+ # Set to false or use --local flag to run directly
35
+ sandbox: true
36
+
37
+ # Docker container name for sandbox mode
38
+ container_name: mobius-sandbox
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "mobius-loop",
3
+ "version": "1.0.0",
4
+ "description": "AI-Powered Development Workflow Tool - Execute Linear/Jira issues with Claude",
5
+ "type": "module",
6
+ "main": "dist/bin/mobius.js",
7
+ "bin": {
8
+ "mobius": "dist/bin/mobius.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/bin/mobius.js",
14
+ "clean": "rm -rf dist",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "claude",
19
+ "linear",
20
+ "jira",
21
+ "ai",
22
+ "automation",
23
+ "workflow",
24
+ "cli"
25
+ ],
26
+ "author": "Dustin Verzal <dustin@tubular.health>",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/Tubular-Health/mobius.git"
30
+ },
31
+ "license": "MIT",
32
+ "engines": {
33
+ "node": ">=18.0.0"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "scripts",
38
+ ".claude",
39
+ "mobius.config.yaml",
40
+ "AGENTS.md"
41
+ ],
42
+ "dependencies": {
43
+ "@inquirer/prompts": "^7.0.0",
44
+ "chalk": "^5.3.0",
45
+ "commander": "^12.0.0",
46
+ "execa": "^8.0.0",
47
+ "which": "^4.0.0",
48
+ "yaml": "^2.3.0"
49
+ },
50
+ "devDependencies": {
51
+ "@mermaid-js/mermaid-cli": "^11.0.0",
52
+ "@types/node": "^20.0.0",
53
+ "@types/which": "^3.0.0",
54
+ "typescript": "^5.0.0"
55
+ }
56
+ }