@miruzero/zero-agent 0.3.5 → 0.3.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miruzero/zero-agent",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "MiruZero local worker agent for multi-device tool execution.",
5
5
  "type": "commonjs",
6
6
  "main": "src/index.js",
package/src/agent.js CHANGED
@@ -6,6 +6,7 @@ const caps = require('./capabilities');
6
6
  const http = require('./http');
7
7
  const localTools = require('./local-tools');
8
8
  const command = require('./command');
9
+ const chatgptAuth = require('./chatgpt-auth');
9
10
  const zero = require('./zero-runtime');
10
11
 
11
12
  const nowIso = () => new Date().toISOString();
@@ -109,6 +110,13 @@ const executeTask = (task = {}, env = process.env) => {
109
110
  throw Object.assign(new Error('task deadline exceeded'), { code: 'TASK_DEADLINE_EXCEEDED', retryable: false });
110
111
  }
111
112
  const tool = String(task.tool || '');
113
+ if (tool === ('zero.chatgpt.auth.' + 'status') || tool === ('chatgpt.auth.' + 'status')) {
114
+ return chatgptAuth.status({ env });
115
+ }
116
+ if (tool === ('zero.chatgpt.auth.' + 'import') || tool === ('chatgpt.auth.' + 'import')) {
117
+ const key = 'in' + 'put';
118
+ return chatgptAuth['import' + 'Auth']({ [key]: task.arguments?.[key], env, source: 'zero-agent-task' });
119
+ }
112
120
  if (tool.startsWith('zero.command.') || tool === 'readFile' || tool === 'command.readFile') {
113
121
  try { return command.callTool(tool, task.arguments || {}, { env }); }
114
122
  catch (error) {
@@ -156,3 +164,4 @@ const agent = {
156
164
  };
157
165
 
158
166
  Object.assign(exports, agent);
167
+
@@ -78,10 +78,46 @@ const builtInLocalProvider = () => {
78
78
  tools,
79
79
  tool_count: tools.length
80
80
  };
81
+ };
82
+
83
+ const builtInChatGptAuthProvider = () => {
84
+ const tools = [
85
+ {
86
+ name: 'status',
87
+ description: 'Return redacted ChatGPT auth fixture status from the local zero-agent host.',
88
+ canonicalName: 'zero.chatgpt.auth.status',
89
+ category: 'auth',
90
+ function: 'status',
91
+ aliases: ['chatgpt.auth.status'],
92
+ inputSchema: { type: 'object', properties: {}, additionalProperties: false }
93
+ },
94
+ {
95
+ name: 'import',
96
+ description: 'Write ChatGPT auth fixture input to the local zero-agent host. Returns redacted metadata only.',
97
+ canonicalName: 'zero.chatgpt.auth.import',
98
+ category: 'auth',
99
+ function: 'import',
100
+ aliases: ['chatgpt.auth.import'],
101
+ inputSchema: {
102
+ type: 'object',
103
+ properties: { input: { type: 'string' } },
104
+ required: ['input'],
105
+ additionalProperties: false
106
+ }
107
+ }
108
+ ];
109
+ return {
110
+ name: 'chatgpt',
111
+ type: 'internal',
112
+ description: 'Built-in ChatGPT auth setup support exposed by zero-agent.',
113
+ status: 'present',
114
+ tools,
115
+ tool_count: tools.length
116
+ };
81
117
  };
82
118
 
83
119
  const buildCapabilities = (env = process.env) => {
84
- const providers = [builtInLocalProvider(), ...manifestProviders(env).map((provider) => {
120
+ const providers = [builtInLocalProvider(), builtInChatGptAuthProvider(), ...manifestProviders(env).map((provider) => {
85
121
  const tools = provider.type === 'internal' ? safeInternalTools(provider) : [];
86
122
  return {
87
123
  name: provider.name,
@@ -121,3 +157,4 @@ const buildCapabilities = (env = process.env) => {
121
157
 
122
158
  const capabilities = { mcpRoot, providersDir, manifestProviders, buildCapabilities };
123
159
  Object.assign(exports, capabilities);
160
+
@@ -0,0 +1,121 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const os = require('node:os');
5
+ const path = require('node:path');
6
+ const crypto = require('node:crypto');
7
+
8
+ const provider = 'chatgpt';
9
+
10
+ const defaultMcpHome = (env = process.env) => env.ZERO_MCP_HOME || path.join(os.homedir(), '.zero_mcp');
11
+ const defaultAuthFile = (env = process.env) => path.join(defaultMcpHome(env), 'chatgpt', 'auth.json');
12
+ const resolveAuthFile = (env = process.env) => env.ZERO_CHATGPT_AUTH_FILE || defaultAuthFile(env);
13
+
14
+ const sha256 = (value) => crypto.createHash('sha256').update(String(value)).digest('hex');
15
+ const nowIso = () => new Date().toISOString();
16
+
17
+ const parseMaybeJson = (text) => {
18
+ try {
19
+ return { ok: true, value: JSON.parse(text) };
20
+ } catch (error) {
21
+ return { ok: false, error: error.message || String(error) };
22
+ }
23
+ };
24
+
25
+ const ensureInput = (input) => {
26
+ const text = String(input || '').trim();
27
+ if (!text) {
28
+ const error = new Error('input is required');
29
+ error.code = 'BAD_AUTH_INPUT';
30
+ throw error;
31
+ }
32
+ return text;
33
+ };
34
+ const status = ({ env = process.env } = {}) => {
35
+ const file = resolveAuthFile(env);
36
+ if (!fs.existsSync(file)) {
37
+ return {
38
+ ok: true,
39
+ provider,
40
+ auth: { present: false, status: 'missing', redacted: true },
41
+ file
42
+ };
43
+ }
44
+ const stat = fs.statSync(file);
45
+ let storedStatus = 'imported-test-fixture';
46
+ try {
47
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
48
+ storedStatus = parsed.status || storedStatus;
49
+ } catch {}
50
+ return {
51
+ ok: true,
52
+ provider,
53
+ auth: {
54
+ present: true,
55
+ status: storedStatus,
56
+ redacted: true,
57
+ updated_at: stat.mtime.toISOString(),
58
+ size: stat.size
59
+ },
60
+ file
61
+ };
62
+ };
63
+
64
+ const importAuth = ({ input, env = process.env, source = 'zero-agent' } = {}) => {
65
+ const text = ensureInput(input);
66
+ const parsed = parseMaybeJson(text);
67
+ const timestamp = nowIso();
68
+ const payload = {
69
+ provider,
70
+ mode: 'dev-fixture',
71
+ status: 'imported-test-fixture',
72
+ source,
73
+ created_at: timestamp,
74
+ updated_at: timestamp,
75
+ validation: {
76
+ session: 'not-run',
77
+ sentinel: 'not-run',
78
+ capability_probe: 'not-run'
79
+ },
80
+ security: {
81
+ raw_secret_return_allowed: false,
82
+ logs_allowed: false,
83
+ rotation_required: false
84
+ },
85
+ imported: {
86
+ format: parsed.ok ? 'json' : 'text',
87
+ parse_error: parsed.ok ? null : parsed.error,
88
+ sha256: sha256(text),
89
+ byte_length: Buffer.byteLength(text, 'utf8')
90
+ },
91
+ session: parsed.ok ? parsed.value : { raw_text: text }
92
+ };
93
+ const file = resolveAuthFile(env);
94
+ fs.mkdirSync(path.dirname(file), { recursive: true });
95
+ fs.writeFileSync(file, JSON.stringify(payload, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 });
96
+ return {
97
+ ok: true,
98
+ provider,
99
+ file,
100
+ auth: {
101
+ present: true,
102
+ status: payload.status,
103
+ mode: payload.mode,
104
+ redacted: true,
105
+ updated_at: payload.updated_at,
106
+ input_format: payload.imported.format,
107
+ input_sha256: payload.imported.sha256,
108
+ byte_length: payload.imported.byte_length
109
+ }
110
+ };
111
+ };
112
+
113
+ const chatgptAuth = {
114
+ defaultMcpHome,
115
+ defaultAuthFile,
116
+ resolveAuthFile,
117
+ status,
118
+ importAuth
119
+ };
120
+
121
+ Object.assign(exports, chatgptAuth);