gipity 1.0.48

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 (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +234 -0
  3. package/dist/__tests__/config.test.d.ts +1 -0
  4. package/dist/__tests__/config.test.js +31 -0
  5. package/dist/__tests__/config.test.js.map +1 -0
  6. package/dist/__tests__/sync.test.d.ts +1 -0
  7. package/dist/__tests__/sync.test.js +89 -0
  8. package/dist/__tests__/sync.test.js.map +1 -0
  9. package/dist/__tests__/utils.test.d.ts +1 -0
  10. package/dist/__tests__/utils.test.js +69 -0
  11. package/dist/__tests__/utils.test.js.map +1 -0
  12. package/dist/api.d.ts +13 -0
  13. package/dist/api.js +85 -0
  14. package/dist/api.js.map +1 -0
  15. package/dist/auth.d.ts +12 -0
  16. package/dist/auth.js +90 -0
  17. package/dist/auth.js.map +1 -0
  18. package/dist/coding-guidelines.d.ts +9 -0
  19. package/dist/coding-guidelines.js +52 -0
  20. package/dist/coding-guidelines.js.map +1 -0
  21. package/dist/commands/agent.d.ts +2 -0
  22. package/dist/commands/agent.js +164 -0
  23. package/dist/commands/agent.js.map +1 -0
  24. package/dist/commands/api.d.ts +2 -0
  25. package/dist/commands/api.js +137 -0
  26. package/dist/commands/api.js.map +1 -0
  27. package/dist/commands/audit.d.ts +2 -0
  28. package/dist/commands/audit.js +70 -0
  29. package/dist/commands/audit.js.map +1 -0
  30. package/dist/commands/browser.d.ts +2 -0
  31. package/dist/commands/browser.js +88 -0
  32. package/dist/commands/browser.js.map +1 -0
  33. package/dist/commands/chat.d.ts +2 -0
  34. package/dist/commands/chat.js +68 -0
  35. package/dist/commands/chat.js.map +1 -0
  36. package/dist/commands/checkpoint.d.ts +2 -0
  37. package/dist/commands/checkpoint.js +67 -0
  38. package/dist/commands/checkpoint.js.map +1 -0
  39. package/dist/commands/credits.d.ts +2 -0
  40. package/dist/commands/credits.js +57 -0
  41. package/dist/commands/credits.js.map +1 -0
  42. package/dist/commands/db.d.ts +2 -0
  43. package/dist/commands/db.js +102 -0
  44. package/dist/commands/db.js.map +1 -0
  45. package/dist/commands/deploy.d.ts +2 -0
  46. package/dist/commands/deploy.js +49 -0
  47. package/dist/commands/deploy.js.map +1 -0
  48. package/dist/commands/file.d.ts +2 -0
  49. package/dist/commands/file.js +85 -0
  50. package/dist/commands/file.js.map +1 -0
  51. package/dist/commands/fn.d.ts +2 -0
  52. package/dist/commands/fn.js +87 -0
  53. package/dist/commands/fn.js.map +1 -0
  54. package/dist/commands/init.d.ts +2 -0
  55. package/dist/commands/init.js +107 -0
  56. package/dist/commands/init.js.map +1 -0
  57. package/dist/commands/login.d.ts +2 -0
  58. package/dist/commands/login.js +62 -0
  59. package/dist/commands/login.js.map +1 -0
  60. package/dist/commands/logout.d.ts +2 -0
  61. package/dist/commands/logout.js +14 -0
  62. package/dist/commands/logout.js.map +1 -0
  63. package/dist/commands/logs.d.ts +2 -0
  64. package/dist/commands/logs.js +39 -0
  65. package/dist/commands/logs.js.map +1 -0
  66. package/dist/commands/memory.d.ts +2 -0
  67. package/dist/commands/memory.js +114 -0
  68. package/dist/commands/memory.js.map +1 -0
  69. package/dist/commands/project.d.ts +2 -0
  70. package/dist/commands/project.js +132 -0
  71. package/dist/commands/project.js.map +1 -0
  72. package/dist/commands/push.d.ts +2 -0
  73. package/dist/commands/push.js +34 -0
  74. package/dist/commands/push.js.map +1 -0
  75. package/dist/commands/rbac.d.ts +2 -0
  76. package/dist/commands/rbac.js +89 -0
  77. package/dist/commands/rbac.js.map +1 -0
  78. package/dist/commands/records.d.ts +2 -0
  79. package/dist/commands/records.js +131 -0
  80. package/dist/commands/records.js.map +1 -0
  81. package/dist/commands/sandbox.d.ts +2 -0
  82. package/dist/commands/sandbox.js +53 -0
  83. package/dist/commands/sandbox.js.map +1 -0
  84. package/dist/commands/scaffold.d.ts +2 -0
  85. package/dist/commands/scaffold.js +38 -0
  86. package/dist/commands/scaffold.js.map +1 -0
  87. package/dist/commands/start-cc.d.ts +2 -0
  88. package/dist/commands/start-cc.js +201 -0
  89. package/dist/commands/start-cc.js.map +1 -0
  90. package/dist/commands/status.d.ts +2 -0
  91. package/dist/commands/status.js +43 -0
  92. package/dist/commands/status.js.map +1 -0
  93. package/dist/commands/sync.d.ts +2 -0
  94. package/dist/commands/sync.js +42 -0
  95. package/dist/commands/sync.js.map +1 -0
  96. package/dist/commands/workflow.d.ts +2 -0
  97. package/dist/commands/workflow.js +163 -0
  98. package/dist/commands/workflow.js.map +1 -0
  99. package/dist/config.d.ts +15 -0
  100. package/dist/config.js +76 -0
  101. package/dist/config.js.map +1 -0
  102. package/dist/index.d.ts +2 -0
  103. package/dist/index.js +65 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/setup.d.ts +23 -0
  106. package/dist/setup.js +168 -0
  107. package/dist/setup.js.map +1 -0
  108. package/dist/sync.d.ts +34 -0
  109. package/dist/sync.js +234 -0
  110. package/dist/sync.js.map +1 -0
  111. package/dist/utils.d.ts +10 -0
  112. package/dist/utils.js +57 -0
  113. package/dist/utils.js.map +1 -0
  114. package/hooks/post-write.sh +17 -0
  115. package/hooks/pre-turn.sh +20 -0
  116. package/package.json +29 -0
package/dist/auth.js ADDED
@@ -0,0 +1,90 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import { decodeJwtExp } from './utils.js';
5
+ const AUTH_DIR = join(homedir(), '.gipity');
6
+ const AUTH_FILE = join(AUTH_DIR, 'auth.json');
7
+ let cached = null;
8
+ export function getAuth() {
9
+ if (cached)
10
+ return cached;
11
+ if (!existsSync(AUTH_FILE))
12
+ return null;
13
+ try {
14
+ cached = JSON.parse(readFileSync(AUTH_FILE, 'utf-8'));
15
+ return cached;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ export function saveAuth(data) {
22
+ mkdirSync(AUTH_DIR, { recursive: true });
23
+ writeFileSync(AUTH_FILE, JSON.stringify(data, null, 2));
24
+ cached = data;
25
+ }
26
+ export function clearAuth() {
27
+ try {
28
+ unlinkSync(AUTH_FILE);
29
+ }
30
+ catch { /* already gone */ }
31
+ cached = null;
32
+ }
33
+ export function isExpired() {
34
+ const auth = getAuth();
35
+ if (!auth)
36
+ return true;
37
+ const expiresAt = new Date(auth.expiresAt).getTime();
38
+ const buffer = 5 * 60 * 1000; // 5 minute buffer
39
+ return Date.now() > expiresAt - buffer;
40
+ }
41
+ export function getTimeRemaining() {
42
+ const auth = getAuth();
43
+ if (!auth)
44
+ return 'not authenticated';
45
+ const ms = new Date(auth.expiresAt).getTime() - Date.now();
46
+ if (ms <= 0)
47
+ return 'expired';
48
+ const mins = Math.floor(ms / 60000);
49
+ if (mins < 60)
50
+ return `${mins}m remaining`;
51
+ return `${Math.floor(mins / 60)}h ${mins % 60}m remaining`;
52
+ }
53
+ export async function refreshTokenIfNeeded() {
54
+ if (!isExpired())
55
+ return;
56
+ const auth = getAuth();
57
+ if (!auth)
58
+ return; // not logged in, caller will handle
59
+ try {
60
+ const config = await import('./config.js');
61
+ const cfg = config.getConfig();
62
+ const apiBase = cfg?.apiBase || 'https://a.gipity.ai';
63
+ const res = await fetch(`${apiBase}/auth/refresh`, {
64
+ method: 'POST',
65
+ headers: { 'Content-Type': 'application/json' },
66
+ body: JSON.stringify({ refreshToken: auth.refreshToken }),
67
+ });
68
+ if (!res.ok) {
69
+ cached = null; // force re-login
70
+ return;
71
+ }
72
+ const json = await res.json();
73
+ const exp = decodeJwtExp(json.accessToken);
74
+ if (!exp) {
75
+ cached = null;
76
+ return;
77
+ }
78
+ const expiresAt = new Date(exp * 1000).toISOString();
79
+ saveAuth({
80
+ accessToken: json.accessToken,
81
+ refreshToken: json.refreshToken,
82
+ email: auth.email,
83
+ expiresAt,
84
+ });
85
+ }
86
+ catch {
87
+ // Refresh failed — caller will see expired auth
88
+ }
89
+ }
90
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shared coding guidelines for Gipity-hosted projects.
3
+ * Single source of truth used by:
4
+ * - server/src/services/skills/web-app-basics.ts (web CLI agent)
5
+ * - tools/gipity-cli/src/setup.ts (CLAUDE.md template for Claude Code)
6
+ *
7
+ * The CLI build copies this file before compiling (see justfile cli-build).
8
+ */
9
+ export declare const CODING_GUIDELINES = "## File Structure\n- **Use src/ convention**: All app files live under `src/` \u2014 `src/index.html`, `src/css/styles.css`, `src/js/main.js`, `src/images/`\n- **Separate files**: Split into `index.html`, `styles.css`, and `app.js` (or `main.js`). Never inline large blocks of CSS or JS in HTML.\n- If the app grows, organize into folders: `src/css/`, `src/js/`, `src/assets/`, `src/sounds/`, `src/images/`, etc.\n- **Use subfolders \u2014 don't flatten**: Reference assets from their folders (e.g. `sounds/click.ogg`, `images/logo.png`). Never copy files to the root just for convenience \u2014 deployed apps serve the full directory tree.\n- Keep `index.html` clean \u2014 it should be structure/markup, not behavior or styling\n\n## HTML\n- Use semantic elements: `<header>`, `<nav>`, `<main>`, `<section>`, `<footer>`, `<article>`\n- Always include `<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">`\n- Add a proper `<title>` and favicon link\n- Unless the user specifies a different CSS framework, include Water.css for automatic styling: `<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/water.css@2/out/water.css\">`\n- Water.css styles semantic HTML automatically (buttons, tables, forms, nav, cards) \u2014 no classes needed. It supports dark/light themes automatically. Add custom CSS on top for app-specific tweaks.\n\n## CSS\n- When using Water.css, it handles base styling, resets, and typography \u2014 don't duplicate what it provides\n- Water.css exposes CSS variables for theming \u2014 override them in `:root` for custom colors/fonts\n- Use CSS custom properties (variables) for app-specific colors, spacing, and fonts\n- Add smooth transitions on interactive elements (buttons, links, hover states)\n\n## JavaScript\n- Use `const`/`let`, arrow functions, template literals, and modern ES6+ syntax\n- Wait for DOM: wrap in `DOMContentLoaded` or place script at end of body\n- Keep functions small and focused\n- Use `addEventListener` \u2014 never inline `onclick` attributes in HTML\n\n## Code Quality\n- **Keep files under ~400 lines** unless the content genuinely requires it (e.g. a long data table, template string, or config object). When logic grows beyond that, split into focused modules (e.g. `utils.js`, `api.js`, `ui.js`).\n- **Don't duplicate code.** If the same logic appears twice, extract it into a shared function. Before writing a new helper, check if one already exists or could be extended.\n- **One responsibility per file.** A file that handles both UI rendering and API calls should be split.\n- **Name things clearly.** Functions, variables, and files should describe what they do \u2014 no `temp`, `data2`, `stuff.js`.\n- **Prefer simple, readable code** over clever code that hides bugs. Flat over nested \u2014 use early returns, avoid deep nesting.\n- **Centralize configuration.** App settings, API URLs, feature flags, and magic numbers should live in a dedicated config file (e.g. `config.js` or `constants.js`), not scattered across the codebase.\n- **Write utility functions** for repeated operations (formatting, validation, API calls). Keep them in a `utils.js` or `helpers.js` file. Small, pure functions are easy to test and reuse.\n\n## Testing\n- **Write tests for new functions** \u2014 especially utility/helper functions. Cover the happy path and edge cases (empty input, null, boundary values).\n- **Don't mock unless absolutely required.** Tests should exercise real code paths. Only mock external paid services (APIs that cost money per call).\n- **E2E tests should hit real infrastructure** (real API, real DB) \u2014 just clean up test data when done.\n- **Test file naming**: `*.test.js` for unit tests, `*.e2e.test.js` for end-to-end tests.\n\n## Deployment\n- **src/ detection**: If a `src/` directory exists, only `src/` is deployed. Otherwise the full project root is deployed.";
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Shared coding guidelines for Gipity-hosted projects.
3
+ * Single source of truth used by:
4
+ * - server/src/services/skills/web-app-basics.ts (web CLI agent)
5
+ * - tools/gipity-cli/src/setup.ts (CLAUDE.md template for Claude Code)
6
+ *
7
+ * The CLI build copies this file before compiling (see justfile cli-build).
8
+ */
9
+ export const CODING_GUIDELINES = `## File Structure
10
+ - **Use src/ convention**: All app files live under \`src/\` — \`src/index.html\`, \`src/css/styles.css\`, \`src/js/main.js\`, \`src/images/\`
11
+ - **Separate files**: Split into \`index.html\`, \`styles.css\`, and \`app.js\` (or \`main.js\`). Never inline large blocks of CSS or JS in HTML.
12
+ - If the app grows, organize into folders: \`src/css/\`, \`src/js/\`, \`src/assets/\`, \`src/sounds/\`, \`src/images/\`, etc.
13
+ - **Use subfolders — don't flatten**: Reference assets from their folders (e.g. \`sounds/click.ogg\`, \`images/logo.png\`). Never copy files to the root just for convenience — deployed apps serve the full directory tree.
14
+ - Keep \`index.html\` clean — it should be structure/markup, not behavior or styling
15
+
16
+ ## HTML
17
+ - Use semantic elements: \`<header>\`, \`<nav>\`, \`<main>\`, \`<section>\`, \`<footer>\`, \`<article>\`
18
+ - Always include \`<meta name="viewport" content="width=device-width, initial-scale=1.0">\`
19
+ - Add a proper \`<title>\` and favicon link
20
+ - Unless the user specifies a different CSS framework, include Water.css for automatic styling: \`<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">\`
21
+ - Water.css styles semantic HTML automatically (buttons, tables, forms, nav, cards) — no classes needed. It supports dark/light themes automatically. Add custom CSS on top for app-specific tweaks.
22
+
23
+ ## CSS
24
+ - When using Water.css, it handles base styling, resets, and typography — don't duplicate what it provides
25
+ - Water.css exposes CSS variables for theming — override them in \`:root\` for custom colors/fonts
26
+ - Use CSS custom properties (variables) for app-specific colors, spacing, and fonts
27
+ - Add smooth transitions on interactive elements (buttons, links, hover states)
28
+
29
+ ## JavaScript
30
+ - Use \`const\`/\`let\`, arrow functions, template literals, and modern ES6+ syntax
31
+ - Wait for DOM: wrap in \`DOMContentLoaded\` or place script at end of body
32
+ - Keep functions small and focused
33
+ - Use \`addEventListener\` — never inline \`onclick\` attributes in HTML
34
+
35
+ ## Code Quality
36
+ - **Keep files under ~400 lines** unless the content genuinely requires it (e.g. a long data table, template string, or config object). When logic grows beyond that, split into focused modules (e.g. \`utils.js\`, \`api.js\`, \`ui.js\`).
37
+ - **Don't duplicate code.** If the same logic appears twice, extract it into a shared function. Before writing a new helper, check if one already exists or could be extended.
38
+ - **One responsibility per file.** A file that handles both UI rendering and API calls should be split.
39
+ - **Name things clearly.** Functions, variables, and files should describe what they do — no \`temp\`, \`data2\`, \`stuff.js\`.
40
+ - **Prefer simple, readable code** over clever code that hides bugs. Flat over nested — use early returns, avoid deep nesting.
41
+ - **Centralize configuration.** App settings, API URLs, feature flags, and magic numbers should live in a dedicated config file (e.g. \`config.js\` or \`constants.js\`), not scattered across the codebase.
42
+ - **Write utility functions** for repeated operations (formatting, validation, API calls). Keep them in a \`utils.js\` or \`helpers.js\` file. Small, pure functions are easy to test and reuse.
43
+
44
+ ## Testing
45
+ - **Write tests for new functions** — especially utility/helper functions. Cover the happy path and edge cases (empty input, null, boundary values).
46
+ - **Don't mock unless absolutely required.** Tests should exercise real code paths. Only mock external paid services (APIs that cost money per call).
47
+ - **E2E tests should hit real infrastructure** (real API, real DB) — just clean up test data when done.
48
+ - **Test file naming**: \`*.test.js\` for unit tests, \`*.e2e.test.js\` for end-to-end tests.
49
+
50
+ ## Deployment
51
+ - **src/ detection**: If a \`src/\` directory exists, only \`src/\` is deployed. Otherwise the full project root is deployed.`;
52
+ //# sourceMappingURL=coding-guidelines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coding-guidelines.js","sourceRoot":"","sources":["../src/coding-guidelines.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8HA0C6F,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const agentCommand: Command;
@@ -0,0 +1,164 @@
1
+ import { Command } from 'commander';
2
+ import { get, post, put, del } from '../api.js';
3
+ import { requireConfig, saveConfig } from '../config.js';
4
+ export const agentCommand = new Command('agent')
5
+ .description('Manage agents')
6
+ .argument('[name]', 'Switch to agent by name')
7
+ .option('--json', 'Output as JSON')
8
+ .action(async (name, opts) => {
9
+ try {
10
+ if (name) {
11
+ // Switch to agent
12
+ const res = await get('/agents');
13
+ const match = res.data.find(a => a.name === name || a.short_guid === name);
14
+ if (!match) {
15
+ console.error(`Agent "${name}" not found.`);
16
+ process.exit(1);
17
+ }
18
+ const config = requireConfig();
19
+ saveConfig({ ...config, agentGuid: match.short_guid, conversationGuid: null });
20
+ if (opts.json) {
21
+ console.log(JSON.stringify({ switched: match.name, guid: match.short_guid }));
22
+ }
23
+ else {
24
+ console.log(`Switched to ${match.name}`);
25
+ }
26
+ return;
27
+ }
28
+ // List agents
29
+ const res = await get('/agents');
30
+ const config = requireConfig();
31
+ if (opts.json) {
32
+ console.log(JSON.stringify(res.data));
33
+ }
34
+ else {
35
+ if (res.data.length === 0) {
36
+ console.log('No agents.');
37
+ }
38
+ else {
39
+ for (const a of res.data) {
40
+ const active = a.short_guid === config.agentGuid ? ' *' : '';
41
+ const def = a.is_default ? ' (default)' : '';
42
+ const model = a.model_preference ? ` [${a.model_preference}]` : '';
43
+ console.log(`${a.name}${active}${def}${model}`);
44
+ }
45
+ }
46
+ }
47
+ }
48
+ catch (err) {
49
+ console.error(`Failed: ${err.message}`);
50
+ process.exit(1);
51
+ }
52
+ });
53
+ agentCommand
54
+ .command('create <name>')
55
+ .description('Create a new agent')
56
+ .option('--model <model>', 'Model preference')
57
+ .option('--switch', 'Switch to new agent after creation')
58
+ .option('--json', 'Output as JSON')
59
+ .action(async (name, opts) => {
60
+ try {
61
+ const body = { name };
62
+ if (opts.model)
63
+ body.modelPreference = opts.model;
64
+ const res = await post('/agents', body);
65
+ if (opts.switch) {
66
+ const config = requireConfig();
67
+ saveConfig({ ...config, agentGuid: res.data.short_guid, conversationGuid: null });
68
+ }
69
+ if (opts.json) {
70
+ console.log(JSON.stringify(res.data));
71
+ }
72
+ else {
73
+ console.log(`Created "${res.data.name}" (${res.data.short_guid})`);
74
+ if (opts.switch)
75
+ console.log('Switched.');
76
+ }
77
+ }
78
+ catch (err) {
79
+ console.error(`Create failed: ${err.message}`);
80
+ process.exit(1);
81
+ }
82
+ });
83
+ agentCommand
84
+ .command('set <field> <value>')
85
+ .description('Set agent field (model, temp)')
86
+ .option('--json', 'Output as JSON')
87
+ .action(async (field, value, opts) => {
88
+ try {
89
+ const config = requireConfig();
90
+ const body = {};
91
+ if (field === 'model')
92
+ body.modelPreference = value;
93
+ else if (field === 'temp' || field === 'temperature')
94
+ body.temperature = parseFloat(value);
95
+ else {
96
+ console.error(`Unknown field: ${field}. Use: model, temp`);
97
+ process.exit(1);
98
+ }
99
+ await put(`/agents/${config.agentGuid}`, body);
100
+ if (opts.json) {
101
+ console.log(JSON.stringify({ success: true, field, value }));
102
+ }
103
+ else {
104
+ console.log(`Set ${field} = ${value}`);
105
+ }
106
+ }
107
+ catch (err) {
108
+ console.error(`Set failed: ${err.message}`);
109
+ process.exit(1);
110
+ }
111
+ });
112
+ agentCommand
113
+ .command('info')
114
+ .description('Show current agent details')
115
+ .option('--json', 'Output as JSON')
116
+ .action(async (opts) => {
117
+ try {
118
+ const config = requireConfig();
119
+ const res = await get(`/agents/${config.agentGuid}`);
120
+ if (opts.json) {
121
+ console.log(JSON.stringify(res.data));
122
+ }
123
+ else {
124
+ const a = res.data;
125
+ console.log(`Name: ${a.name}`);
126
+ console.log(`GUID: ${a.short_guid}`);
127
+ console.log(`Model: ${a.model_preference || '(default)'}`);
128
+ console.log(`Temp: ${a.temperature ?? '(default)'}`);
129
+ if (a.voice_provider)
130
+ console.log(`Voice: ${a.voice_provider}/${a.voice_id}`);
131
+ console.log(`Created: ${new Date(a.created_at).toLocaleDateString()}`);
132
+ }
133
+ }
134
+ catch (err) {
135
+ console.error(`Info failed: ${err.message}`);
136
+ process.exit(1);
137
+ }
138
+ });
139
+ agentCommand
140
+ .command('delete <name>')
141
+ .description('Delete an agent')
142
+ .option('--json', 'Output as JSON')
143
+ .action(async (name, opts) => {
144
+ try {
145
+ const res = await get('/agents');
146
+ const match = res.data.find(a => a.name === name || a.short_guid === name);
147
+ if (!match) {
148
+ console.error(`Agent "${name}" not found.`);
149
+ process.exit(1);
150
+ }
151
+ await del(`/agents/${match.short_guid}`);
152
+ if (opts.json) {
153
+ console.log(JSON.stringify({ deleted: match.name }));
154
+ }
155
+ else {
156
+ console.log(`Deleted "${match.name}".`);
157
+ }
158
+ }
159
+ catch (err) {
160
+ console.error(`Delete failed: ${err.message}`);
161
+ process.exit(1);
162
+ }
163
+ });
164
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const apiCommand: Command;
@@ -0,0 +1,137 @@
1
+ import { Command } from 'commander';
2
+ import { readFileSync } from 'fs';
3
+ import { get, put, del } from '../api.js';
4
+ import { requireConfig } from '../config.js';
5
+ export const apiCommand = new Command('api')
6
+ .description('Manage API procedures');
7
+ apiCommand
8
+ .command('list')
9
+ .description('List API procedures')
10
+ .option('--json', 'Output as JSON')
11
+ .action(async (opts) => {
12
+ try {
13
+ const config = requireConfig();
14
+ const res = await get(`/projects/${config.projectGuid}/procedures`);
15
+ if (opts.json) {
16
+ console.log(JSON.stringify(res.data));
17
+ }
18
+ else {
19
+ if (res.data.length === 0) {
20
+ console.log('No API procedures defined.');
21
+ }
22
+ else {
23
+ for (const p of res.data) {
24
+ const paramStr = p.params.length > 0
25
+ ? ` (${p.params.map(pr => `${pr.name}:${pr.type}`).join(', ')})`
26
+ : '';
27
+ console.log(`${p.name} ${p.method}/${p.auth_level} → ${p.database_name}${paramStr}`);
28
+ if (p.description)
29
+ console.log(` ${p.description}`);
30
+ }
31
+ }
32
+ }
33
+ }
34
+ catch (err) {
35
+ console.error(`List failed: ${err.message}`);
36
+ process.exit(1);
37
+ }
38
+ });
39
+ apiCommand
40
+ .command('get <name>')
41
+ .description('Show procedure details')
42
+ .option('--json', 'Output as JSON')
43
+ .action(async (name, opts) => {
44
+ try {
45
+ const config = requireConfig();
46
+ const res = await get(`/projects/${config.projectGuid}/procedures/${encodeURIComponent(name)}`);
47
+ if (opts.json) {
48
+ console.log(JSON.stringify(res.data, null, 2));
49
+ }
50
+ else {
51
+ const p = res.data;
52
+ console.log(`Name: ${p.name}`);
53
+ console.log(`Method: ${p.method}`);
54
+ console.log(`Auth: ${p.auth_level}`);
55
+ console.log(`Database: ${p.database_name}`);
56
+ if (p.description)
57
+ console.log(`Desc: ${p.description}`);
58
+ if (p.params.length > 0) {
59
+ console.log(`Params: ${p.params.map(pr => `${pr.name}:${pr.type}${pr.source ? ` (${pr.source})` : ''}`).join(', ')}`);
60
+ }
61
+ console.log(`SQL:\n${p.sql_text}`);
62
+ }
63
+ }
64
+ catch (err) {
65
+ console.error(`Get failed: ${err.message}`);
66
+ process.exit(1);
67
+ }
68
+ });
69
+ apiCommand
70
+ .command('define <name>')
71
+ .description('Create or update an API procedure')
72
+ .requiredOption('--sql <sql>', 'SQL with $1, $2, ... placeholders (or @filename to read from file)')
73
+ .requiredOption('--database <db>', 'Target database name')
74
+ .option('--method <method>', 'read or write', 'write')
75
+ .option('--auth <level>', 'public, user, or member', 'public')
76
+ .option('--params <params>', 'Param definitions as JSON array: [{"name":"x","type":"string"}]', '[]')
77
+ .option('--description <desc>', 'Procedure description')
78
+ .option('--json', 'Output as JSON')
79
+ .action(async (name, opts) => {
80
+ try {
81
+ const config = requireConfig();
82
+ // Read SQL from file if prefixed with @
83
+ let sql = opts.sql;
84
+ if (sql.startsWith('@')) {
85
+ sql = readFileSync(sql.slice(1), 'utf-8');
86
+ }
87
+ let params;
88
+ try {
89
+ params = JSON.parse(opts.params);
90
+ }
91
+ catch {
92
+ console.error('Invalid --params JSON. Example: \'[{"name":"color","type":"string"},{"name":"count","type":"int"}]\'');
93
+ process.exit(1);
94
+ }
95
+ const body = {
96
+ sql,
97
+ database: opts.database,
98
+ method: opts.method,
99
+ auth_level: opts.auth,
100
+ params,
101
+ description: opts.description || null,
102
+ };
103
+ const res = await put(`/projects/${config.projectGuid}/procedures/${encodeURIComponent(name)}`, body);
104
+ if (opts.json) {
105
+ console.log(JSON.stringify(res.data));
106
+ }
107
+ else {
108
+ console.log(`${res.data.action === 'created' ? 'Created' : 'Updated'} procedure "${name}".`);
109
+ console.log(`URL: https://a.gipity.ai/api/${config.projectGuid}/call/${name}`);
110
+ }
111
+ }
112
+ catch (err) {
113
+ console.error(`Define failed: ${err.message}`);
114
+ process.exit(1);
115
+ }
116
+ });
117
+ apiCommand
118
+ .command('delete <name>')
119
+ .description('Delete an API procedure')
120
+ .option('--json', 'Output as JSON')
121
+ .action(async (name, opts) => {
122
+ try {
123
+ const config = requireConfig();
124
+ await del(`/projects/${config.projectGuid}/procedures/${encodeURIComponent(name)}`);
125
+ if (opts.json) {
126
+ console.log(JSON.stringify({ success: true, name }));
127
+ }
128
+ else {
129
+ console.log(`Deleted "${name}".`);
130
+ }
131
+ }
132
+ catch (err) {
133
+ console.error(`Delete failed: ${err.message}`);
134
+ process.exit(1);
135
+ }
136
+ });
137
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/commands/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAkB7C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,uBAAuB,CAAC,CAAC;AAExC,UAAU;KACP,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAwB,aAAa,MAAM,CAAC,WAAW,aAAa,CAAC,CAAC;QAE3F,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;oBACzB,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;wBAClC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;wBAChE,CAAC,CAAC,EAAE,CAAC;oBACP,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,UAAU,OAAO,CAAC,CAAC,aAAa,GAAG,QAAQ,EAAE,CAAC,CAAC;oBACvF,IAAI,CAAC,CAAC,WAAW;wBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,UAAU;KACP,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,wBAAwB,CAAC;KACrC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,IAAI,EAAE,EAAE;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAsB,aAAa,MAAM,CAAC,WAAW,eAAe,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAErH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;YAC7C,IAAI,CAAC,CAAC,WAAW;gBAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3H,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,UAAU;KACP,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,mCAAmC,CAAC;KAChD,cAAc,CAAC,aAAa,EAAE,oEAAoE,CAAC;KACnG,cAAc,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;KACzD,MAAM,CAAC,mBAAmB,EAAE,eAAe,EAAE,OAAO,CAAC;KACrD,MAAM,CAAC,gBAAgB,EAAE,yBAAyB,EAAE,QAAQ,CAAC;KAC7D,MAAM,CAAC,mBAAmB,EAAE,iEAAiE,EAAE,IAAI,CAAC;KACpG,MAAM,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;KACvD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,IAAI,EAAE,EAAE;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;QAE/B,wCAAwC;QACxC,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACnB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,MAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,sGAAsG,CAAC,CAAC;YACtH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG;YACX,GAAG;YACH,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,UAAU,EAAE,IAAI,CAAC,IAAI;YACrB,MAAM;YACN,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;SACtC,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,GAAG,CACnB,aAAa,MAAM,CAAC,WAAW,eAAe,kBAAkB,CAAC,IAAI,CAAC,EAAE,EACxE,IAAI,CACL,CAAC;QAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,eAAe,IAAI,IAAI,CAAC,CAAC;YAC7F,OAAO,CAAC,GAAG,CAAC,gCAAgC,MAAM,CAAC,WAAW,SAAS,IAAI,EAAE,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,UAAU;KACP,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,IAAI,EAAE,EAAE;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;QAC/B,MAAM,GAAG,CAAuB,aAAa,MAAM,CAAC,WAAW,eAAe,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE1G,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const auditCommand: Command;
@@ -0,0 +1,70 @@
1
+ import { Command } from 'commander';
2
+ import { get } from '../api.js';
3
+ import { requireConfig } from '../config.js';
4
+ export const auditCommand = new Command('audit')
5
+ .description('Query audit logs');
6
+ auditCommand
7
+ .command('list')
8
+ .description('List recent audit events')
9
+ .option('--type <type>', 'Filter by event type (e.g., record.create)')
10
+ .option('--entity <type>', 'Filter by entity type')
11
+ .option('--action <action>', 'Filter by action (create, update, delete)')
12
+ .option('--since <date>', 'Start date (ISO format)')
13
+ .option('--limit <n>', 'Max entries', '20')
14
+ .option('--json', 'Output as JSON')
15
+ .action(async (opts) => {
16
+ try {
17
+ const config = requireConfig();
18
+ const params = new URLSearchParams();
19
+ if (opts.type)
20
+ params.set('type', opts.type);
21
+ if (opts.entity)
22
+ params.set('entity_type', opts.entity);
23
+ if (opts.action)
24
+ params.set('action', opts.action);
25
+ if (opts.since)
26
+ params.set('since', opts.since);
27
+ params.set('limit', opts.limit);
28
+ const res = await get(`/projects/${config.projectGuid}/audit?${params}`);
29
+ if (opts.json) {
30
+ console.log(JSON.stringify(res.data));
31
+ }
32
+ else if (res.data.length === 0) {
33
+ console.log('No audit events found.');
34
+ }
35
+ else {
36
+ for (const e of res.data) {
37
+ const ts = new Date(e.created_at).toLocaleString();
38
+ const entity = e.entity_type ? `${e.entity_type}${e.entity_id ? ':' + e.entity_id : ''}` : '';
39
+ console.log(`${ts} ${e.event_type} ${e.action} ${entity}`);
40
+ }
41
+ }
42
+ }
43
+ catch (err) {
44
+ console.error(`List failed: ${err.message}`);
45
+ process.exit(1);
46
+ }
47
+ });
48
+ auditCommand
49
+ .command('count')
50
+ .description('Count audit events')
51
+ .option('--type <type>', 'Filter by event type')
52
+ .option('--entity <type>', 'Filter by entity type')
53
+ .option('--json', 'Output as JSON')
54
+ .action(async (opts) => {
55
+ try {
56
+ const config = requireConfig();
57
+ const params = new URLSearchParams();
58
+ if (opts.type)
59
+ params.set('type', opts.type);
60
+ if (opts.entity)
61
+ params.set('entity_type', opts.entity);
62
+ const res = await get(`/projects/${config.projectGuid}/audit/count?${params}`);
63
+ console.log(opts.json ? JSON.stringify(res.data) : `${res.data.count} events`);
64
+ }
65
+ catch (err) {
66
+ console.error(`Count failed: ${err.message}`);
67
+ process.exit(1);
68
+ }
69
+ });
70
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const browserCommand: Command;