ai-summon 0.0.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 (61) hide show
  1. package/.claude/commands/speckit.analyze.md +184 -0
  2. package/.claude/commands/speckit.checklist.md +294 -0
  3. package/.claude/commands/speckit.clarify.md +177 -0
  4. package/.claude/commands/speckit.constitution.md +78 -0
  5. package/.claude/commands/speckit.implement.md +121 -0
  6. package/.claude/commands/speckit.plan.md +81 -0
  7. package/.claude/commands/speckit.specify.md +204 -0
  8. package/.claude/commands/speckit.tasks.md +108 -0
  9. package/.claude/settings.local.json +23 -0
  10. package/.prettierignore +5 -0
  11. package/.prettierrc.json +10 -0
  12. package/.specify/memory/constitution.md +72 -0
  13. package/.specify/scripts/bash/check-prerequisites.sh +166 -0
  14. package/.specify/scripts/bash/common.sh +113 -0
  15. package/.specify/scripts/bash/create-new-feature.sh +97 -0
  16. package/.specify/scripts/bash/setup-plan.sh +60 -0
  17. package/.specify/scripts/bash/update-agent-context.sh +738 -0
  18. package/.specify/templates/agent-file-template.md +28 -0
  19. package/.specify/templates/checklist-template.md +40 -0
  20. package/.specify/templates/plan-template.md +111 -0
  21. package/.specify/templates/spec-template.md +115 -0
  22. package/.specify/templates/tasks-template.md +250 -0
  23. package/CLAUDE.md +199 -0
  24. package/PRD.md +268 -0
  25. package/README.md +171 -0
  26. package/dist/ai-summon.d.ts +2 -0
  27. package/dist/ai-summon.js +73 -0
  28. package/dist/commands/ide/index.d.ts +3 -0
  29. package/dist/commands/ide/index.js +253 -0
  30. package/dist/commands/init.d.ts +4 -0
  31. package/dist/commands/init.js +55 -0
  32. package/dist/commands/url.d.ts +4 -0
  33. package/dist/commands/url.js +223 -0
  34. package/dist/types/index.d.ts +40 -0
  35. package/dist/types/index.js +1 -0
  36. package/dist/util.d.ts +16 -0
  37. package/dist/util.js +109 -0
  38. package/eslint.config.js +47 -0
  39. package/package.json +47 -0
  40. package/specs/001-cloud-login-feature/contracts/cloud-command.ts +82 -0
  41. package/specs/001-cloud-login-feature/contracts/config-service.ts +170 -0
  42. package/specs/001-cloud-login-feature/data-model.md +269 -0
  43. package/specs/001-cloud-login-feature/plan.md +91 -0
  44. package/specs/001-cloud-login-feature/quickstart.md +366 -0
  45. package/specs/001-cloud-login-feature/research.md +290 -0
  46. package/specs/001-cloud-login-feature/spec.md +195 -0
  47. package/specs/001-cloud-login-feature/tasks.md +235 -0
  48. package/specs/001-cloud-scp-command/contracts/cloud-scp-api.ts +402 -0
  49. package/specs/001-cloud-scp-command/data-model.md +424 -0
  50. package/specs/001-cloud-scp-command/plan.md +124 -0
  51. package/specs/001-cloud-scp-command/quickstart.md +536 -0
  52. package/specs/001-cloud-scp-command/research.md +345 -0
  53. package/specs/001-cloud-scp-command/spec.md +248 -0
  54. package/specs/001-cloud-scp-command/tasks.md +434 -0
  55. package/src/ai-summon.ts +88 -0
  56. package/src/commands/ide/index.ts +322 -0
  57. package/src/commands/init.ts +64 -0
  58. package/src/commands/url.ts +262 -0
  59. package/src/types/index.ts +49 -0
  60. package/src/util.ts +146 -0
  61. package/tsconfig.json +21 -0
package/src/util.ts ADDED
@@ -0,0 +1,146 @@
1
+ import { readFileSync, existsSync, readdirSync, mkdirSync, writeFileSync } from 'fs';
2
+ import { join, basename } from 'path';
3
+ import { dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { homedir } from 'os';
6
+ import chalk from 'chalk';
7
+ import { HshConfig } from './types/index.js';
8
+
9
+ export const getPackageJson = () => {
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
13
+ return packageJson;
14
+ };
15
+
16
+ export const getConfigPath = (): string => {
17
+ const dir = join(homedir(), '.ai');
18
+ mkdirSync(dir, { recursive: true });
19
+ return join(dir, 'config.json');
20
+ };
21
+
22
+ export const readConfig = (): HshConfig => {
23
+ const configPath = getConfigPath();
24
+
25
+ if (!existsSync(configPath)) {
26
+ console.log(
27
+ chalk.yellow(
28
+ `Configuration file not found: ${configPath}\n` +
29
+ `Run "ai init" to create it and set your workingDirectory.`
30
+ )
31
+ );
32
+ process.exit(1);
33
+ }
34
+
35
+ const configContent = readFileSync(configPath, 'utf-8');
36
+ const config = JSON.parse(configContent);
37
+
38
+ // If workingDirectory is configured but repos/yiren are not, initialize them
39
+ if (config.workingDirectory && !config.repos) {
40
+ return {
41
+ workingDirectory: config.workingDirectory,
42
+ repos: {},
43
+ yiren: config.yiren || {},
44
+ urls: config.urls,
45
+ urlGroups: config.urlGroups,
46
+ };
47
+ }
48
+
49
+ return config as HshConfig;
50
+ };
51
+
52
+ /**
53
+ * Recursively scan directory for Git repositories
54
+ * Returns list of { name, path, topLevelFolder } objects
55
+ */
56
+ export interface GitRepository {
57
+ name: string;
58
+ path: string;
59
+ topLevelFolder: string; // Top-level folder name relative to workingDirectory
60
+ }
61
+
62
+ interface IdeReposCacheFileV1 {
63
+ version: 1;
64
+ workingDirectory: string;
65
+ updatedAt: number;
66
+ repos: GitRepository[];
67
+ }
68
+
69
+ const ensureAiDir = (): string => {
70
+ const dir = join(homedir(), '.ai');
71
+ mkdirSync(dir, { recursive: true });
72
+ return dir;
73
+ };
74
+
75
+ const getIdeReposCachePath = (): string => {
76
+ const dir = ensureAiDir();
77
+ return join(dir, 'ide-repos-cache.json');
78
+ };
79
+
80
+ export const readIdeReposCache = (workingDirectory: string): GitRepository[] | null => {
81
+ const cachePath = getIdeReposCachePath();
82
+ if (!existsSync(cachePath)) return null;
83
+
84
+ try {
85
+ const raw = readFileSync(cachePath, 'utf-8');
86
+ const parsed = JSON.parse(raw) as Partial<IdeReposCacheFileV1>;
87
+
88
+ if (parsed.version !== 1) return null;
89
+ if (parsed.workingDirectory !== workingDirectory) return null;
90
+ if (!Array.isArray(parsed.repos)) return null;
91
+
92
+ return parsed.repos as GitRepository[];
93
+ } catch {
94
+ return null;
95
+ }
96
+ };
97
+
98
+ export const writeIdeReposCache = (workingDirectory: string, repos: GitRepository[]): void => {
99
+ const cachePath = getIdeReposCachePath();
100
+ const payload: IdeReposCacheFileV1 = {
101
+ version: 1,
102
+ workingDirectory,
103
+ updatedAt: Date.now(),
104
+ repos,
105
+ };
106
+ writeFileSync(cachePath, JSON.stringify(payload, null, 2), 'utf-8');
107
+ };
108
+
109
+ export const findGitRepositories = (workingDirectory: string): GitRepository[] => {
110
+ const repositories: GitRepository[] = [];
111
+
112
+ const scanDirectory = (dir: string, topLevelFolder: string = '/'): void => {
113
+ try {
114
+ // Check if current directory contains .git folder
115
+ if (existsSync(join(dir, '.git'))) {
116
+ repositories.push({
117
+ name: basename(dir),
118
+ path: dir,
119
+ topLevelFolder,
120
+ });
121
+ return; // Stop recursing into this directory
122
+ }
123
+
124
+ // Continue scanning subdirectories
125
+ const entries = readdirSync(dir, { withFileTypes: true });
126
+
127
+ for (const entry of entries) {
128
+ if (entry.isDirectory()) {
129
+ const fullPath = join(dir, entry.name);
130
+
131
+ // Determine top-level folder for this entry
132
+ const isTopLevel = dir === workingDirectory;
133
+ const currentTopLevel = isTopLevel ? entry.name : topLevelFolder;
134
+
135
+ scanDirectory(fullPath, currentTopLevel);
136
+ }
137
+ }
138
+ } catch {
139
+ // Silently skip directories with permission errors
140
+ // This will be enhanced in future iterations
141
+ }
142
+ };
143
+
144
+ scanDirectory(workingDirectory);
145
+ return repositories;
146
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "outDir": "dist",
8
+ "rootDir": "src",
9
+ "declaration": true,
10
+ "types": ["node"],
11
+ "skipLibCheck": true,
12
+ "resolveJsonModule": true,
13
+ "esModuleInterop": true,
14
+ "baseUrl": "./",
15
+ "paths": {
16
+ "*": ["*", "*.js"]
17
+ }
18
+ },
19
+ "include": ["src/**/*"],
20
+ "exclude": ["node_modules", "dist"]
21
+ }